> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usecobalt.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Service

> Queues a service (an episode visit with form documentation) for creation in the provider's EMR system.

A service is an episode visit written to the patient's chart together with its form documentation (for example a scored questionnaire such as GAD-7). Services are created using an asynchronous processing model, so creating one is not instantaneous.

Instead of leaving your POST request hanging until completion, we immediately return a success response if the request is properly formed. We then notify you via a webhook when the service has been written to the EMR.

This gives you flexibility around your user experience. For example, when you first make the `/services` call you can display a **Processing** status to your user, and when you receive the webhook notification you can update that to **Completed**.

<Note>
  Creating services is currently supported for **Credible**.
</Note>

### How a service is created

Processing a service runs an ordered chain against the EMR:

1. **Team to episode** — the patient is assigned to the given `team`. When the client has no open episode under that team, the assignment opens one. An existing episode is reused.
2. **Service type** — the `service_type` is resolved against the client's live billing matrix. A service type that is not billable for the client fails the service (see [Failure](#failure)).
3. **Form documentation** — the `answers` you supply are validated against the synced form definition (`form_id`) and written on the service. For a scored questionnaire, per-question scores are entered and totals and risk bands are derived by the EMR.
4. **Read-back** — after signing, the service is re-read from the EMR to confirm it persisted before the success webhook is sent.

### Request Parameters

#### Required Fields

* **patient\_mrn** (string, required): The patient's medical record number. For Credible this is the client id. The patient must already be synced to Cobalt.
* **team** (string, required): Team name (or numeric team id) that owns the episode. Assigning the client to the team opens the episode when one does not already exist. The name is matched case-insensitively, preferring an exact match over a partial one.
* **service\_type** (string, required): The service type to add, by name or numeric visit-type id (for example `"GAD-7"`). Must be billable for the client — that is, present in the client's billing matrix.
* **form\_id** (string, required): EMR form id whose answers you are providing — the `emr_form_id` of a form from [`GET /v1/forms`](/api-reference/forms/get). Required when the service type documents a form.
* **answers** (object, required): Form answers keyed by EMR question id (the `emrQuestionId` of each question in the form definition — see [`GET /v1/forms/{id}`](/api-reference/forms/get-by-id)). For a scored questionnaire, provide the numeric score for each scored question; totals and risk bands are derived automatically. Answers are validated against the synced form definition before the service is written.

#### Optional Fields

* **service\_date** (string, optional): Service date in `YYYY-MM-DD` format. Defaults to today. Cannot be in the future.
* **callback\_urls** (array of strings, optional): URLs to receive the completion webhook for this service, in addition to your account webhook.

### Example Request

```bash theme={null}
curl -X POST https://api.usecobalt.com/v1/services \
-H 'Content-Type: application/json' \
-H 'client_id: ci_live_198908HJDKJSH98789OHKJL' \
-H 'client_secret: cs_live_9827hofdsklOYYHJLJh' \
-H 'access_token: 493JKLHIU98789hLKH9HHJH' \
-d '{
    "patient_mrn": "1234567",
    "team": "Adult Outpatient",
    "service_type": "GAD-7",
    "form_id": "392",
    "service_date": "2026-08-26",
    "answers": {
        "453149": "3",
        "453150": "2",
        "453156": "Very difficult"
    }
}'
```

### Example Response

```json theme={null}
{
    "success": true,
    "message": "Service processing. A webhook event will be sent upon completion.",
    "service_id": "123e4567e89b12d3a456426614174000",
    "job_id": 12345
}
```

The response includes:

* **service\_id**: Cobalt service ID (UUID without dashes). This is echoed back in the webhook payload so you can correlate the two.
* **job\_id**: Job execution identifier for tracking the async operation.

### Error Responses

#### Missing Required Field

```json theme={null}
{
    "success": false,
    "message": "Missing required field: patient_mrn"
}
```

#### Answers Not An Object

```json theme={null}
{
    "success": false,
    "message": "answers must be an object keyed by EMR question id."
}
```

#### Invalid Service Date

```json theme={null}
{
    "success": false,
    "message": "service_date must be a valid date (YYYY-MM-DD)."
}
```

```json theme={null}
{
    "success": false,
    "message": "service_date cannot be in the future."
}
```

#### User Not Found

```json theme={null}
{
    "success": false,
    "message": "User not found."
}
```

This indicates an issue with your access token.

#### Unsupported EMR

```json theme={null}
{
    "success": false,
    "message": "Creating services is not supported for [EMR Name]."
}
```

Your EMR system may not currently support service creation.

### Webhook Notifications

When the service has finished processing, we send a webhook to your registered endpoint.

#### Success

```json theme={null}
{
    "id": "<id-of-webhook-response>",
    "access_token_reference_id": "<access-token-reference-id>",
    "object": "event",
    "created": "2026-08-26T10:30:00.000Z",
    "type": "service.created",
    "data": {
        "service_id": "123e4567e89b12d3a456426614174000",
        "emr_service_id": "927341",
        "emr_episode_id": "88214",
        "patient_mrn": "1234567"
    }
}
```

The webhook data includes:

* **service\_id**: The Cobalt service ID you received in the response.
* **emr\_service\_id**: The service's id in the EMR.
* **emr\_episode\_id**: The episode the service was written under (reused if one was already open, otherwise the episode opened by the team assignment).
* **patient\_mrn**: The patient's medical record number.

#### Failure

```json theme={null}
{
    "id": "<id-of-webhook-response>",
    "access_token_reference_id": "<access-token-reference-id>",
    "object": "event",
    "created": "2026-08-26T10:35:00.000Z",
    "type": "service.failed",
    "data": {
        "service_id": "123e4567e89b12d3a456426614174000",
        "emr_service_id": null,
        "patient_mrn": "1234567",
        "failure_reason": "Service type 'GAD-7' not available for client 1234567 (not in billing matrix)"
    }
}
```

Transient problems are retried automatically and do not emit a webhook until they are resolved or the attempts are exhausted. A `service.failed` event is sent once, when the failure is permanent. Common `failure_reason` values:

* `Credible team '<team>' not found for client <mrn>` — the team name or id did not match a team the client can be assigned to.
* `Service type '<type>' not available for client <mrn> (not in billing matrix)` — the service type is not billable for the client.
* `Missing required answers: <question ids>` — one or more required form questions were not answered.


## OpenAPI

````yaml POST /services
openapi: 3.0.0
info:
  title: Cobalt API
  version: 1.0.1
  description: API for interacting with Cobalt's EHR integration services
servers:
  - url: https://api.usecobalt.com/v1
security:
  - ClientCredentials: []
    ClientSecret: []
    AccessToken: []
paths:
  /services:
    post:
      summary: Create Service
      description: >-
        Queues a service (an episode visit with form documentation) for creation
        in the provider's EMR system. This is an asynchronous operation that
        returns immediately with a service_id and job_id, and sends a webhook
        notification upon completion. Currently supported for Credible.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - patient_mrn
                - team
                - service_type
                - form_id
                - answers
              properties:
                patient_mrn:
                  type: string
                  description: >-
                    The patient's medical record number (for Credible, the
                    client id). The patient must already be synced to Cobalt.
                  example: '1234567'
                team:
                  type: string
                  description: >-
                    Team name (or numeric team id) that owns the episode.
                    Assigning the client to the team opens the episode when one
                    does not already exist.
                  example: Adult Outpatient
                service_type:
                  type: string
                  description: >-
                    Service type to add, by name or numeric visit-type id (e.g.
                    "GAD-7"). Must be billable for the client (present in the
                    client's billing matrix).
                  example: GAD-7
                form_id:
                  type: string
                  description: >-
                    EMR form id whose answers are provided. Required when the
                    service type documents a form.
                  example: '392'
                answers:
                  type: object
                  additionalProperties: true
                  description: >-
                    Form answers keyed by EMR question id. For a scored
                    questionnaire provide the numeric score for each scored
                    question; totals and risk bands are derived automatically.
                    Validated against the synced form definition.
                  example:
                    '453149': '3'
                    '453150': '2'
                    '453156': Very difficult
                service_date:
                  type: string
                  description: >-
                    Service date (YYYY-MM-DD). Defaults to today. Cannot be in
                    the future.
                  example: '2026-08-26'
                callback_urls:
                  type: array
                  items:
                    type: string
                  description: >-
                    URLs to receive the completion webhook for this service, in
                    addition to the account webhook.
      responses:
        '200':
          description: Service queued successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
                    example: >-
                      Service processing. A webhook event will be sent upon
                      completion.
                  service_id:
                    type: string
                    description: >-
                      Cobalt service ID (UUID without dashes). Echoed back in
                      the webhook payload.
                  job_id:
                    type: integer
                    description: Job execution identifier for tracking the async operation.
        '400':
          description: Bad request - validation error
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
                    example: answers must be an object keyed by EMR question id.
        '404':
          description: User not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
                    example: User not found.
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
                    example: Error processing the services request.
components:
  securitySchemes:
    ClientCredentials:
      type: apiKey
      in: header
      name: client_id
    ClientSecret:
      type: apiKey
      in: header
      name: client_secret
    AccessToken:
      type: apiKey
      in: header
      name: access_token

````