Reimbursements

In this section, we walk through understanding reimbursements in the Spend & Expense platform.

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 more information about the complete list of Spend & Expense reimbursement operations.

Uploading a receipt for a reimbursement

Uploading receipt images for a reimbursement is a two-step process.

Generating 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.

📘

NOTE

Use the same receipt url value when you create a reimbursement with POST /v3/spend/reimbursements.

Uploading 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. When you get an HTTP 200 response, the image is successfully uploaded.

curl '{upload_url}'
--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 status of the response
if response.status_code == 200:
    print("File uploaded successfully!")
else:
    print(f"Failed to upload. Status code: {response.status_code}")
    print(response.text)

Creating a reimbursement

In your POST /v3/spend/reimbursements request, set the required fields.

FieldDescription
budgetIdBILL-generated ID of the budget for the reimbursement. Funds for the reimbursement are taken from this budget.
userIdBILL-generated ID of the user to be reimbursed.

Note: This user must be assigned to the budget specified by the budgetId.
amountOut-of-pocket expense amount
noteReimbursement note. Use this field to provide more information about the expense.
merchantNameMerchant name for the out-of-pocket expense
occurredDateDate when the user made the out-of-pocket expense. This value is in the yyyy-MM-dd format.
receiptsReceipts information. In the receipts array, set the url and filename values for each receipt.

See the /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 (budgetId). The request is submitted by the budget user (userId). 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 '{
  "budgetId": "{budget_id}",
  "userId": "{user_id}",
  "occurredDate": "2024-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 id 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.


{
    "id": "{reimbursement_id}",
    "amount": 50.00,
    "fundRequestAmount": 0.00,
    "fundRequestBudgetAmount": 0.00,
    "merchantName": "Jasmine Thai",
    "note": "Team lunch",
    "submittedTime": "2024-12-26T23:12:04Z",
    "occurredTime": "2024-12-25T00:00:00Z",
    "retired": false,
    "status": "AWAITING_APPROVAL",
    "type": "PURCHASE",
    "statusHistory": [
        {
            "actorId": "{user_id}",
            "actorRole": "SUBMITTER",
            "occurredTime": "2024-12-26T23:12:04Z",
            "note": "Team lunch",
            "status": "AWAITING_APPROVAL"
        }
    ],
    "budgetId": "{budget_id}",
    "userId": "{user_id}",
    "receipts": [
        {
            "url": "{receipt_url}",
            "filename": "{file_name_with_extension}"
        }
    ],
    "customFields": [
        {
            // custom_fields_details
        }
    ]
}

Approving a reimbursement

In your POST /v3/spend/reimbursements/{reimbursementId}/action request, set the required fields.

FieldDescription
reimbursementIdBILL-generated ID of the reimbursement transaction
actionReimbursement 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/{reimbursementId}/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.

{
    "id": "{reimbursement_id}",
    "amount": 50.00,
    "fundRequestAmount": 0.00,
    "fundRequestBudgetAmount": 0.00,
    "merchantName": "Jasmine Thai",
    "note": "Team lunch",
    "submittedTime": "2024-12-26T23:12:04Z",
    "occurredTime": "2024-12-25T00:00:00Z",
    "retired": false,
    "status": "APPROVED",
    "type": "PURCHASE",
    "statusHistory": [
        {
            "actorId": "{admin_user_id}",
            "actorRole": "ADMIN",
            "occurredTime": "2025-01-02T23:12:04Z",
            "note": "Team lunch expense approved",
            "status": "APPROVED"
        },
        {
            "actorId": "{user_id}",
            "actorRole": "SUBMITTER",
            "occurredTime": "2024-12-26T23:12:04Z",
            "note": "Team lunch",
            "status": "AWAITING_APPROVAL"
        }
    ],
    "budgetId": "{budget_id}",
    "userId": "{user_id}",
    "receipts": [
        {
            "url": "{receipt_url}",
            "filename": "{file_name_with_extension}"
        }
    ],
    "customFields": [
        {
            // custom_fields_details
        }
    ]
}

See the /v3/spend/reimbursements API for more information about the complete list of Spend & Expense reimbursement operations.