# CRM · Benefits

Part of AppEngine API Documentation. Full index: https://appengine.appmint.io/documentation.md
## POST /crm/workflows/benefit-application

**Create a benefit application workflow**

`operationId: CRMController_createBenefitWorkflow`

Scaffolds a standard benefit-application workflow from the built-in template. Customise its stages afterwards through the workflow API.

#### Signature

```http
POST /crm/workflows/benefit-application (body) -> The created workflow
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /crm/workflows/benefit-application/{name}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Workflow name.

```json
{
  "name": "benefit-application"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The created workflow |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /crm/workflows/benefit-application/{name}

**Get the benefit application workflow**

`operationId: CRMController_getBenefitWorkflow`

Fetches a benefit-application workflow by name, or omit the segment to find it by the datatype it is bound to — the reliable way to ask which pipeline benefit applications run on.

#### Signature

```http
GET /crm/workflows/benefit-application/{name} (name: string) -> The workflow definition
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /crm/workflows/benefit-application`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `name` | path | string | yes | Workflow name. Omit to find by owner datatype. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The workflow definition |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /crm/benefit-enrollments

**List benefit enrolments**

`operationId: CRMController_getEnrollments`

Lists benefit enrolments with optional filters. The operator queue for reviewing applications — filter on `status` for those awaiting a decision.

#### Signature

```http
GET /crm/benefit-enrollments (customerId?: string, benefit?: string, status?: string) -> Matching enrolments
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /crm/benefit-enrollments/{enrollmentId}/action`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `customerId` | query | string | — | Filter to one customer. |
| `benefit` | query | string | — | Filter to one benefit. |
| `status` | query | string | — | Filter by enrolment status. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Matching enrolments |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /crm/benefit-enrollments/{enrollmentId}/action

**Review, approve or reject an enrolment**

`operationId: CRMController_updateEnrollmentStatus`

Acts on a benefit enrolment. `action` decides what happens: `review` marks it as being examined, `approve` accepts it, `reject` declines it.

Notes are recorded against the decision and are what an applicant is shown when rejected, so write them for that audience.

#### Signature

```http
POST /crm/benefit-enrollments/{enrollmentId}/action (enrollmentId: string, body) -> The updated enrolment
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `DELETE /crm/benefit-enrollments/{enrollmentId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `enrollmentId` | path | string | yes | Enrolment id. |

### Request body

The decision.

```json
{
  "action": "approve",
  "notes": "Eligibility confirmed"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated enrolment |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /crm/benefit-enrollments/{enrollmentId}

**Delete a benefit enrolment**

`operationId: CRMController_deleteEnrollment`

Deletes an enrolment **and all its associated data**, including the submitted application. This is a hard delete with nothing to restore — reject the enrolment instead when you need to keep the record of what was applied for.

#### Signature

```http
DELETE /crm/benefit-enrollments/{enrollmentId} (enrollmentId: string) -> Deletion result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Removes associated application data too. Prefer `reject` where an audit trail matters.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /crm/benefit-enrollments/{enrollmentId}/action`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `enrollmentId` | path | string | yes | Enrolment id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Deletion result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

