Reimbursements
Spend & Expense API reimbursements
In this section, we walk through understanding reimbursements in BILL Spend & Expense.
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/image-upload-url.
curl --request POST \
--url 'https://gateway.stage.bill.com/connect/v3/spend/reimbursements/image-upload-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.
curl -i -X PUT '{image-upload-url}' \
-H 'Content-Type: image/jpeg' \
--upload-file {file_name_with_extension}import requests
url = "{image-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 |
|---|---|
budgetUuid | BILL-generated UUID of the budget for the reimbursement. Funds for the reimbursement are taken from this budget. |
userUuid | BILL-generated ID of the user to be reimbursed. Note: This user must be assigned to the budget specified by the |
amount | Out-of-pocket expense amount |
note | Reimbursement note. Use this field to provide more information about the expense. |
merchantName | Out-of-pocket expense merchant name |
occurredDate | Out-of-pocket expense date. The value is in the yyyy-MM-dd format. |
receipts | Receipts information. In the receipts array, set the url and filename values for each receipt. |
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": "2026-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": "2026-12-26T23:12:04Z",
"occurredTime": "2026-12-25T00:00:00Z",
"retired": false,
"status": "AWAITING_APPROVAL",
"type": "PURCHASE",
"statusHistory": [
{
"actorUuid": "\{user_uuid}",
"actorId": "\{user_id}",
"actorRole": "SUBMITTER",
"occurredTime": "2026-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": "2026-12-26T23:12:04Z",
"occurredTime": "2026-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": "2026-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 1 day ago
