---
title: "Create an expense for the authenticated employee"
method: POST
path: "/v1/employee/expenses"
tags: ["Expenses"]
---

# Create an expense for the authenticated employee

`POST /v1/employee/expenses`

## Request

- Base URL: `https://gateway.remote.com`
- URL: `https://gateway.remote.com/v1/employee/expenses`
- Auth: one of:
  - OAuth 2
    - Client credentials
    - Token URL: `/auth/oauth2/token` scopes: `employment_payments`
  - OAuth 2
    - Client credentials
    - Token URL: `/auth/oauth2/token` scopes: `all:write`
  - OAuth 2
    - Authorization code: `/auth/oauth2/authorize`
    - Token URL: `/auth/oauth2/token` scopes: `https://gateway.remote.com/employment.manage`
  - OAuth 2
    - Authorization code: `/auth/oauth2/authorize`
    - Token URL: `/auth/oauth2/token` scopes: `expense:write`
  - OAuth 2
    - Authorization code: `/auth/oauth2/authorize`
    - Token URL: `/auth/oauth2/token` scopes: `all:write`

Creates a new expense record for the current employee.

## Authentication

This endpoint accepts any one of the following token types:

- **Employee-scoped access token** (`OAuth2Assertion`) — obtained through the `urn:ietf:params:oauth:grant-type:jwt-bearer` grant. See [OAuth Assertion](https://developer.remote.com/docs/authorization-method-oauth-assertion).
- **Company-scoped access token** (`OAuth2AuthorizationCode`) — obtained by the employee through the Authorization Code flow or the Refresh Token flow. See [Authentication for partners](https://developer.remote.com/docs/authentication-for-partners).

## Scopes

Any one of the scopes in a token type's row is enough. `all:write` works too.

| Token type | Category | Read only Scope | Write only Scope (read access implicit) |
|---|---|---|---|
| Employee-scoped access token | Manage expenses (`employment_payments`) | - | - |
| Company-scoped access token | Manage expenses (`employment_payments`) | - | Manage expenses (`expense:write`) |

## Request body

- ParamsToCreateEmployeeExpense: Params for creating an expense as the authenticated employee. The employment is implied by the access token, so `employment_id` is not accepted. `reviewer_id` and `reviewed_at` are also omitted — they only apply to manager-created expenses. Category selection mirrors the company endpoint: use either `category` (legacy enum, deprecated but supported) or `expense_category_slug` (recommended). When both are provided, `expense_category_slug` wins. `expense_category_slug` must be the `slug` of a category listed for the employee by `GET /v1/employee/expense-categories`. Slugs differ between sandbox and production, so read them from that endpoint instead of storing them. A slug that isn't listed is refused, unless `category` is also sent: then `category` is used.
  - `amount` integer, required: The expense amount in the specified currency, in cents.
  - `category` 'car_rental' | 'coworking_office' | 'education_training' | 'entertainment' | 'flight' | 'fuel' | 'gifts' | 'insurance' | 'lodging' | 'meals' | 'other' | 'parking_toll' | 'subscription' | 'tech_equipment' | 'telecommunication' | 'transport' | 'utilities' | 'vaccination_testing' | 'visa' | 'wellness' | 'coworking' | 'home_office' | 'phone_utilities' | 'travel', nullable: Categories allowed for an expense (legacy, deprecated).<br/> Note: `coworking`, `home_office`, `phone_utilities`, `travel` are deprecated and will be removed in the future.
  - `currency` string, required: The three-letter code for the expense currency.<br/> Examples: `"USD"`, `"EUR"`, `"CAD"`
  - `expense_category_slug` string, nullable: Slug of a category listed by `GET /v1/employee/expense-categories` for the employee (recommended). Takes precedence over legacy category field.
  - `expense_date` string, required: Date of the purchase, which must be in the past
  - `receipt` Base64File: All the params needed upload a base64 file.
    - `content` string, binary, required: The content in base64 encoding.
    - `name` string, required: The file name.
  - `receipts` Base64File[]
    - `content` string, binary, required: The content in base64 encoding.
    - `name` string, required: The file name.
  - `tax_amount` integer: The tax portion of the expense amount, in cents. Use 0 if no tax applies.
  - `timezone` string: [TZ identifier](https://www.iana.org/time-zones)
  - `title` string, required: A short description of the expense (e.g., "New keyboard", "Team dinner").

## Response `201`

Created

- SuccessResponse: A generic success response returned by operations that don't produce a specific resource (e.g., updates, deletes).
  - `data` object, required
    - `status` string: The result status. Always `"ok"` for successful operations.

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `403`: Forbidden
- `422`: Unprocessable Entity

---

[API](https://skmtc.dev/remote-com/apis/employee-actions.md) - [All operations](https://skmtc.dev/remote-com/apis/employee-actions/llms.txt) - [OpenAPI document](https://skmtc.dev/remote-com/apis/employee-actions/revisions/ccad61420ac2?raw)
