# Card expenses via API

List, retrieve, and update card expenses programmatically using the Spend API.

The Card Expenses API lets you retrieve approved card expenses from Airwallex and mark them as synced after ingesting them into your ERP or accounting system. This prevents re-processing and keeps your records in sync.

## Before you begin

- [Obtain your access token](/api/authentication/api_access_token) by authenticating to Airwallex using your unique Client ID and [API key](https://www.airwallex.com/docs/developer-tools/api/manage-api-keys.md). You can [create scoped API keys](https://www.airwallex.com/docs/developer-tools/api/manage-api-keys#scoped-api-keys.md) in **Settings** > **Developer** > **API keys** in the Airwallex web app. Spend resources require Organization-level permissions.
- Familiarize yourself with the [Spend data model](https://www.airwallex.com/docs/spend/how-airwallex-spend-works.md).

## List card expenses

To retrieve a list of card expenses, call the [List card expenses](/api/spend/expenses/list) endpoint. You can use query parameters to filter results by status, sync status, and pagination.

1. Send the request with your desired filters:

   ```shell
   curl -G \
     'https://api.sandbox.airwallex.com/api/v1/spend/expenses' \
     --data-urlencode 'status=APPROVED' \
     --data-urlencode 'sync_status=NOT_SYNCED' \
     -H 'Authorization: Bearer {{ACCESS_TOKEN}}'
   ```

2. Review the response:

   ```json
   {
     "items": [
       {
         "account_id": "acct_a2y0pxz3m4k5hoZldn97hjzp",
         "approvers": [
         ],
         "billing_amount": "1234.56",
         "billing_currency": "USD",
         "card_id": "bdfd278d-14f8-4d12-a04f-a7a1871babd2",
         "created_at": "2025-01-01T00:00:00Z",
         "description": "Business lunch with client",
         "id": "f865c064-57bb-4ca0-9793-54011e00cb53",
         "legal_entity_id": "le_U3jlHqQRNHWn2zAKeeT8sg",
         "merchant": "Restaurant ABC",
         "settled_at": "2025-03-03T00:00:00Z",
         "status": "APPROVED",
         "sync_status": "NOT_SYNCED",
         "card_transaction": {
           "status": "CLEARED",
           "amount": "1234.56",
           "currency": "USD"
         },
         "updated_at": "2025-02-02T00:00:00Z"
       },
       {
         "account_id": "acct_a2y0pxz3m4k5hoZldn97hjzp",
         "approvers": [
           "approver1@airwallex.com",
           "approver2@airwallex.com"
         ],
         "billing_amount": "567.89",
         "billing_currency": "USD",
         "card_id": "7d2faf05-a771-4964-92ed-0b65ef3ea04b",
         "created_at": "2025-01-01T01:00:00Z",
         "description": "Team dinner",
         "id": "313c9a4f-2e7b-40f2-9b89-ebb08bc7d856",
         "legal_entity_id": "le_U3jlHqQRNHWn2zAKeeT8sg",
         "merchant": "Restaurant XYZ",
         "settled_at": "2025-03-03T01:00:00Z",
         "status": "APPROVED",
         "sync_status": "NOT_SYNCED",
         "card_transaction": {
           "status": "CLEARED",
           "amount": "567.89",
           "currency": "USD"
         },
         "updated_at": "2025-02-02T01:00:00Z"
       }
     ],
     "page_after": "eyJwYWdlX2JlZm9yZSI6IjIwMjUtMDctMDFUMDA6MDA6MDBaIn0=",
     "page_before": "eyJwYWdlX2JlZm9yZSI6IjIwMjUtMDctMDFUMDA6MDA6MDBaIn0="
   }
   ```

Key query parameters include:

| Parameter         | Description                                                                                                                                                                                |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `status`          | Filter by expense statuses. Possible values are `DRAFT`, `AWAITING_APPROVAL`, `REJECTED`, `APPROVED`, `ARCHIVED`, `DELETED`.                                                               |
| `sync_status`     | Filter by sync status (`NOT_SYNCED`, `SYNCED`, `SYNC_FAILED`, `READY_TO_SYNC`).                                                                                                            |
| `from_created_at` | Filter expenses created on or after this timestamp (ISO 8601).                                                                                                                             |
| `to_created_at`   | Filter expenses created on or before this timestamp (ISO 8601).                                                                                                                            |
| `legal_entity_id` | Filter expenses by legal entity ID.                                                                                                                                                        |
| `page`            | A bookmark for use in pagination to retrieve either the next page or the previous page of results. You can fetch the value for this identifier from the response of the previous API call. |

## Get card expense details

To retrieve the full details of a specific expense, including attachments, line items, accounting fields, and comments, call the [Get card expense](/api/spend/expenses/retrieve) endpoint.

1. Use the `id` from the list response:

   ```shell
   curl -G \
     'https://api.sandbox.airwallex.com/api/v1/spend/expenses/{{ID}}' \
     -H 'Authorization: Bearer {{ACCESS_TOKEN}}'
   ```

2. The response includes complete expense details:

   ```json
   {
     "account_id": "acct_a2y0pxz3m4k5hoZldn97hjzp",
     "accounting_field_selections": [
       {
         "source_id": "d8e2f0ff-8081-4db6-8333-4e011fe9561d",
         "type": "MERCHANT",
         "value": "Airwallex",
         "value_label": "Airwallex"
       }
     ],
     "approvers": [
       "approver1@airwallex.com",
       "approver2@airwallex.com"
     ],
     "attachments": [
       {
         "content_type": "image/jpeg",
         "created_at": "2025-02-02T00:00:00Z",
         "file_name": "receipt.jpg",
         "file_url": "https://www.airwallex.com/receipt.jpg",
         "id": "0fd62109-cfc0-4c94-86a5-d01c42506b76"
       }
     ],
     "billing_amount": "100.0",
     "billing_currency": "USD",
     "card_id": "93eed14b-104d-4f40-ae1d-3633c6538276",
     "comments": [
       {
         "content": "Please review this expense.",
         "created_at": "2025-02-02T08:00:00Z",
         "created_by": "user1@airwallex.com"
       }
     ],
     "created_at": "2025-01-01T00:00:00Z",
     "description": "This is a description of the expense.",
     "id": "ba46f0ff-8081-4db6-8333-4e011fe9561d",
     "legal_entity_id": "le_U3jlHqQRNHWn2zAKeeT8sg",
     "line_items": [
       {
         "accounting_field_selections": [
           {
             "source_id": "c9fcfdee-f943-45c9-abaa-45df1601ae04",
             "name": "Cost Center",
             "type": "OTHER",
             "value": "Office Expense",
             "external_id": "a7e44855-e7f3-47ce-be50-182b666d543c",
             "value_label": "Office Expense"
           }
         ],
         "description": "Office supplies purchase",
         "id": "a12fca5e-4aeb-4adb-85b0-428b4f078aba",
         "transaction_amount": "100.00"
       }
     ],
     "merchant": "Airwallex",
     "settled_at": "2025-03-03T00:00:00Z",
     "status": "APPROVED",
     "sync_status": "SYNCED",
     "card_transaction": {
       "status": "AUTHORIZED",
       "amount": "100.0",
       "currency": "USD"
     },
     "updated_at": "2025-02-02T00:00:00Z"
   }
   ```

Use root-level `accounting_field_selections` for the merchant (`type: MERCHANT`). Use `line_items[].accounting_field_selections` for GL accounts, tax codes, and custom fields. See [Accounting field selections](https://www.airwallex.com/docs/spend/how-airwallex-spend-works#accounting-field-selections.md).

## Update sync status

After you persist an expense to your system, mark it as synced to prevent re-processing.

1. Call the [Sync card expense status](/api/spend/expenses/sync) endpoint:

   ```shell
   curl -X POST \
     'https://api.sandbox.airwallex.com/api/v1/spend/expenses/{{ID}}/sync' \
     -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \
     -H 'Content-Type: application/json' \
     -d '{
       "sync_status": "SYNCED"
     }'
   ```

2. The response confirms the updated status:

   ```json
   {
     "id": "ba46f0ff-8081-4db6-8333-4e011fe9561d",
     "sync_status": "SYNCED"
   }
   ```

## Next steps

Now that you can manage card expenses via the API, explore these related guides:

- [Reimbursements via API](https://www.airwallex.com/docs/spend/expenses/reimbursements-via-api.md)
- [Set up Spend webhooks](https://www.airwallex.com/docs/spend/get-started/set-up-spend-webhooks.md)
- [Error codes](https://www.airwallex.com/docs/spend/troubleshooting/error-codes.md)