---
title: "Enrollment"
description: "Grant or remove Blend-ed course access from a trusted external commerce or CRM system."
source: "https://docs.blend-ed.com/blendx-discovery/enrollment/"
---

# Enrollment

Use the client enrollment endpoints when payment happens outside Blend-ed. Call them from a trusted server after the external system has confirmed the payment or refund.

Both routes require:

```
clientapisecret: <CLIENT_API_SECRET>Content-Type: application/json
```
## Grant course access
```
POST /blendxapi/enrollments/client/enroll/
```
```
{  "email": "learner@example.com",  "course_id": "267ce96d-1454-4292-aa42-1a0487c7eaaa",  "mode": "honor"}
```

| Field | Required | Description |
| --- | --- | --- |
| `email` | Yes | Learner email and the join key for pending registration. |
| `course_id` | Yes | BlendX/Hasura course UUID returned by discovery. |
| `mode` | Yes | Valid Open edX enrollment mode. |

For an existing account:

```
{  "message": "User enrolled successfully",  "status": "success",  "enrollment_state": "enrolled"}
```
For an email without an account:

```
{  "message": "User has no account; auto-enrollment queued and registration email sent",  "status": "success",  "enrollment_state": "pending_registration"}
```
The learner must register with the same email address. Blend-ed then resolves the pending enrollment automatically.

The operation is safe to retry. Repeating an existing enrollment updates its mode rather than adding a duplicate; repeating a pending enrollment leaves one pending record.

## Remove course access
```
POST /blendxapi/enrollments/client/unenroll/
```
```
{  "email": "learner@example.com",  "course_id": "267ce96d-1454-4292-aa42-1a0487c7eaaa"}
```
For a registered learner, the API removes the Hasura enrollment record and its trigger requests the matching Open edX unenrollment. For an unregistered email, it cancels the pending auto-enrollment.

The route returns `200` when the course exists even if there was nothing to remove. This makes refund and chargeback retries safe.

> **Note**
> Open edX unenrollment still respects the platform’s `safe_to_unenroll` policy. For example, access retained through another product relationship may remain in place even though the client request completed successfully.

## Error handling

| Status | Meaning |
| --- | --- |
| `400` | Invalid body, unsupported mode, or enrollment operation failed. |
| `401` | Missing or invalid `clientapisecret`. |
| `404` | The course UUID does not exist in BlendX. |
| `500` | Required server configuration, such as the service account, is missing. |

Retry network failures and `5xx` responses with backoff. Do not retry `401` or `404` until configuration or identifiers change.
