# Create Reimbursement

**POST** `/users/{user_id}/reimbursements`

Base URL: `https://live.savewithsail.com/api/v1`

Initiates a reimbursement: pays the user back from their own benefit account for a set of `eligible` expenses. Requires the `benefit_account` key scope, and the `benefit_account` product on the funding account's connection. Processing is asynchronous: the reimbursement is created `pending` and progresses through `submitted`/`processing` to `completed` or `failed`, with a `reimbursement.status_changed` webhook per transition. On completion the underlying expenses transition to `reimbursed`. Expenses must be `eligible` and not already part of an in-flight reimbursement (`409 conflict` otherwise).

## Authorization

- PartnerKey (http, bearer)

## Path parameters

- `user_id` (string, required)
  The Sail user id.

## Body

Content type: `application/json`

- `expense_ids` (string[], required)
  Expenses to reimburse. All must be `eligible` and belong to this user.
- `account_id` (string, required)
  The benefit account to pay from. Its owning connection must have the `benefit_account` product.

Example:

```json
{
  "expense_ids": [
    "string"
  ],
  "account_id": "string"
}
```

## Responses

### 201

Reimbursement created. Processing has begun.

- `id` (string)
  The Sail reimbursement id.
- `status` ("pending" | "submitted" | "processing" | "completed" | "failed")
  The reimbursement's current processing status.
- `amount` (number<float>)
  Sum of the included expenses, USD.
- `account_id` (string)
  The funding account. Join to /accounts/{account_id} for provider and balance context.
- `expenses` (object[])
  The expenses included in this reimbursement.
  - `id` (string)
    The Sail expense id.
  - `name` (string)
    The expense's display name.
  - `amount` (number<float>)
    The expense's amount, USD.
  - `date` (string<date>)
    The expense's transaction date.
- `receipt_url` (string)
  Reimbursement receipt document. Populated once `completed`; present on the single-resource GET only.
- `submitted_at` (string<date-time>)
  When the reimbursement was submitted for processing.
- `completed_at` (string<date-time>)
  When the reimbursement completed. Null while still in progress.

Example:

```json
{
  "id": "reimb_8c1f",
  "status": "pending",
  "amount": 0,
  "account_id": "string",
  "expenses": [
    {
      "id": "string",
      "name": "string",
      "amount": 0,
      "date": "2024-01-01"
    }
  ],
  "receipt_url": "string",
  "submitted_at": "1970-01-01T00:00:00.000Z",
  "completed_at": "1970-01-01T00:00:00.000Z"
}
```

### 409

`conflict`: an expense is not `eligible`, or is already in an in-flight reimbursement.

### default

Standard error envelope covering 400, 401, 403, 404, 429, and 500.

- `error` (object)
  The error detail.
  - `code` (string)
    Machine-readable code, e.g. `not_found`, `token_scope_mismatch`, `product_not_enabled`, `insufficient_key_scope`, `insufficient_token_scope`, `user_token_required`, `user_token_expired`, `invalid_user_token`, `invalid_key_configuration`, `connection_not_reconnectable`, `rate_limited`.
  - `message` (string)
    Human-readable error message. May change, so match on `error.code` instead.
  - `param` (string)
    The request field that caused the error, when applicable. Null otherwise.

Example:

```json
{
  "error": {
    "code": "string",
    "message": "string",
    "param": "string"
  }
}
```