Reimbursements
Spend & Expense API reimbursements
In this section, we walk through understanding reimbursements in BILL Spend & Expense.
Useuuidin the Spend & Expense APIIn February 2025, BILL introduced UUIDs in the Spend & Expense API for further improving its security standards. All API responses include both
idanduuidvalues.As of July 9, 2025, the Spend & Expense
idvalues are being deprecated. Bothidanduuidvalues will continue to be available in all API responses. We strongly recommend that you useuuidinstead ofidin all your Spend & Expense API operations.
What is a reimbursement?
A reimbursement is a request to be repaid from budget funds for an out-of-pocket expense. Reimbursements enable business transactions without a charge card (physical or virtual card) to be included in the Spend & Expense platform.
Spend & Expense users with the ADMIN user role can approve or deny reimbursement requests.
See the /v3/spend/reimbursements API for the complete list of available operations.
Upload a receipt for a reimbursement
Uploading receipt images for a reimbursement is a two-step process.
Generate an upload URL
Generate an upload URL with POST /v3/spend/reimbursements/upload-image-url.
curl --request POST \
--url 'https://gateway.stage.bill.com/connect/v3/spend/reimbursements/upload-image-url' \
--header 'apiToken: {api_token}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json'In the response, an upload url is available. Use this value to upload an image for a receipt in the next step.
Use the uploadurlin your reimbursementUse the same upload
urlvalue when you create a reimbursement withPOST /v3/spend/reimbursements.
Upload an image
Upload an image by sending a PUT request with the upload url value.
In this example, an image is uploaded to the provided url location. To upload a PNG image, set the content type as image/png in the request. When you get an HTTP 200 response, the image is successfully uploaded.
Upload JPG or PNG imagesBILL supports JPG and PNG file formats for transaction images.
curl '{upload_url}'
--Content-Type: image/jpeg
--upload-file {file_name_with_extension}import requests
url = "{upload_url}"
# Open the file in binary mode
with open("{file_name_with_extension}", "rb") as file:
response = requests.put(url, data=file)
# Check the response status
if response.status_code == 200:
print("File uploaded successfully!")
else:
print(f"Failed to upload. Status code: {response.status_code}")
print(response.text)Create a reimbursement
In your POST /v3/spend/reimbursements request, set the required fields.
Field | Description |
|---|---|
| BILL-generated UUID of the budget for the reimbursement. Funds for the reimbursement are taken from this budget. |
| BILL-generated ID of the user to be reimbursed. Note: This user must be assigned to the budget specified by the |
| Out-of-pocket expense amount |
| Reimbursement note. Use this field to provide more information about the expense. |
| Merchant name for the out-of-pocket expense |
| Date when the user made the out-of-pocket expense. This value is in the |
| Receipts information. In the |
See the POST /v3/spend/reimbursements API for information about the complete list of reimbursements fields you can set.
Sample request
In this cURL example, a reimbursement transaction of $50 is created for the provided budget (budgetUuid). The request is submitted by the budget user (userUuid). In addition, the receipt image url and filename is added to the request.
curl --request POST \
--url 'https://gateway.stage.bill.com/connect/v3/spend/reimbursements' \
--header 'apiToken: {api_token}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"budgetUuid": "{budget_uuid}",
"userUuid": "\{user_uuid}",
"occurredDate": "2025-12-25",
"note": "Team lunch",
"merchantName": "Jasmine Thai",
"amount": 50,
"receipts": [
{
"url": "{receipt_url}",
"filename": "{file_name_with_extension}"
}
]
}'Response
In the response, a BILL-generated reimbursement transaction uuid is available. The statusHistory information provides details about the different stages of the reimbursement transaction. When the reimbursement is approved, the statusHistory information is updated.
{
"uuid": "{reimbursement_uuid}",
"id": "{reimbursement_id}",
"amount": 50.00,
"fundRequestAmount": 0.00,
"fundRequestBudgetAmount": 0.00,
"merchantName": "Jasmine Thai",
"note": "Team lunch",
"submittedTime": "2025-12-26T23:12:04Z",
"occurredTime": "2025-12-25T00:00:00Z",
"retired": false,
"status": "AWAITING_APPROVAL",
"type": "PURCHASE",
"statusHistory": [
{
"actorUuid": "\{user_uuid}",
"actorId": "\{user_id}",
"actorRole": "SUBMITTER",
"occurredTime": "2025-12-26T23:12:04Z",
"note": "Team lunch",
"status": "AWAITING_APPROVAL"
}
],
"budgetUuid": "{budget_uuid}",
"budgetId": "{budget_id}",
"userUuid": "\{user_uuid}",
"userId": "\{user_id}",
"receipts": [
{
"url": "{receipt_url}",
"filename": "{file_name_with_extension}"
}
],
"customFields": [
{
// custom_fields_details
}
]
}Approve a reimbursement
In your POST /v3/spend/reimbursements/{reimbursementUuid}/action request, set the required fields.
| Field | Description |
|---|---|
reimbursementUuid | BILL-generated UUID of the reimbursement transaction |
action | Reimbursement approval decision (APPROVE or DENY) |
Sample request
In this cURL example, a reimbursement request is marked as approved. An approval note is added to the approval. Spend & Expense users with the ADMIN user role can approve or deny reimbursement requests.
curl --request POST \
--url 'https://gateway.stage.bill.com/connect/v3/spend/reimbursements/{reimbursement_uuid}/action' \
--header 'apiToken: {api_token}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"action": "APPROVE",
"note": "Team lunch expense approved"
}'Response
In the response, the statusHistory information is updated in the reimbursement transaction. The status is set as APPROVED.
{
"uuid": "{reimbursement_uuid}",
"id": "{reimbursement_id}",
"amount": 50.00,
"fundRequestAmount": 0.00,
"fundRequestBudgetAmount": 0.00,
"merchantName": "Jasmine Thai",
"note": "Team lunch",
"submittedTime": "2025-12-26T23:12:04Z",
"occurredTime": "2025-12-25T00:00:00Z",
"retired": false,
"status": "APPROVED",
"type": "PURCHASE",
"statusHistory": [
{
"actorUuid": "{admin_user_uuid}",
"actorId": "{admin_user_id}",
"actorRole": "ADMIN",
"occurredTime": "2026-01-02T23:12:04Z",
"note": "Team lunch expense approved",
"status": "APPROVED"
},
{
"actorUuid": "{user_uuid}",
"actorId": "{user_id}",
"actorRole": "SUBMITTER",
"occurredTime": "2025-12-26T23:12:04Z",
"note": "Team lunch",
"status": "AWAITING_APPROVAL"
}
],
"budgetUuid": "{budget_uuid}",
"budgetId": "{budget_id}",
"userUuid": "\{user_uuid}",
"userId": "\{user_id}",
"receipts": [
{
"url": "{receipt_url}",
"filename": "{file_name_with_extension}"
}
],
"customFields": [
{
// custom_fields_details
}
]
}See the /v3/spend/reimbursements API for the complete list of available operations.
Updated 5 days ago
