Update expense report for organization
Updates an expense report. When the action query parameter is provided, performs the specified action instead of a field update. Otherwise, updates the allowed fields (name, comment, customFields, expenseRecords); any other fields in the request body are silently ignored.
moveToNextStep moves a report that is in TRANSFER or TRANSFER_TO_RECIPIENT to the next step of its send chain: to the next recipient, or to SENT when the chain is complete. forwardToApprovalOrBooking forwards a report that is ON_HOLD back into the approval or booking flow. Both are support tools and are restricted to the developer role. The report must belong to the organization in the path; a report of another organization is answered with 404 EXPENSE_REPORT_NOT_FOUND even when the caller administers that organization.
sendReminder reminds the owner of the report about it, and takes { "message": "..." } as its body. Only reports that carry an invoice reference can be reminded, and only organization administrators and standard API keys may use it.
curl --request PUT \
--url https://stage-api.findity.com/api/v1/admin/organizations/{organizationId}/reports/{reportId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Business Trip Stockholm",
"comment": "Updated comment for the expense report",
"expenseRecords": [
{
"id": "a73efe636a4d47359f3c28c3024b6d23"
}
],
"customFields": [
{
"fieldDefinitionId": "2b965c866b634698811dabf45a491089",
"value": true
}
]
}
'{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Business Trip Stockholm",
"personId": "123e4567-e89b-12d3-a456-426614174000",
"organizationId": "550e8400-e29b-41d4-a716-446655440001",
"dateCreated": "2024-01-15T09:30:00Z",
"lastUpdated": "2024-01-16T14:45:00Z",
"reportNumber": "ER-2024-001",
"comment": "Business trip to Stockholm for client meeting",
"emailRecipients": "manager@company.com;finance@company.com",
"status": "APPROVED",
"processStatus": "PROCESSED",
"type": "MANUAL",
"reimbursement": 2580.5,
"reimbursementCurrency": "SEK",
"sent": "2024-01-16T10:00:00Z",
"paid": "2024-01-18T00:00:00Z",
"approved": "2024-01-17T15:30:00Z",
"previewUrl": "https://expense.findity.com/api/expensereports/550e8400-e29b-41d4-a716-446655440000",
"meta": {
"autoApproval": {
"status": "REJECTED",
"reasons": [
{
"reason": "POLICY_FAILURE",
"description": "Violates the company's expense policy."
},
{
"reason": "WEEKEND_PURCHASE_DATE",
"description": "The purchase was made during a weekend."
}
]
}
},
"expenseRecords": [
{
"id": "rec1-550e8400-e29b-41d4-a716-446655440000",
"status": "APPROVED",
"personId": "123e4567-e89b-12d3-a456-426614174000",
"organizationId": "550e8400-e29b-41d4-a716-446655440001",
"categoryId": "cat1-550e8400-e29b-41d4-a716-446655440000",
"expenseReportId": "550e8400-e29b-41d4-a716-446655440000",
"dateCreated": "2024-01-15T09:30:00Z",
"lastUpdated": "2024-01-16T14:45:00Z",
"reimbursement": 1250,
"reimbursementCurrency": "SEK",
"rejectComment": null,
"meta": {
"categoryIconUrl": "https://expense.findity.com/api/resources/8a5f867e9b204742a8cc2ca2b6c57358"
}
},
{
"id": "rec2-550e8400-e29b-41d4-a716-446655440000",
"status": "APPROVED",
"personId": "123e4567-e89b-12d3-a456-426614174000",
"organizationId": "550e8400-e29b-41d4-a716-446655440001",
"categoryId": "cat2-550e8400-e29b-41d4-a716-446655440000",
"expenseReportId": "550e8400-e29b-41d4-a716-446655440000",
"dateCreated": "2024-01-15T18:45:00Z",
"lastUpdated": "2024-01-16T14:45:00Z",
"reimbursement": 1330.5,
"reimbursementCurrency": "SEK",
"rejectComment": null,
"meta": {
"categoryIconUrl": "https://expense.findity.com/api/resources/9b6f977f8c305753b9dd3db3c7d68469"
}
}
],
"ownerName": "John Doe",
"firstName": "John",
"lastName": "Doe",
"organizationName": "Acme Corporation",
"organizationNumber": "556123-4567",
"organizationLanguage": "en",
"organizationUseNewDimensions": true,
"organizationRequiresAttestation": false,
"organizationUsesPaymentBasis": true,
"expenseRecordCount": 2,
"totalAmount": 2580.5,
"userCanModifyReports": true,
"userCanSendReports": true,
"reportGroup": 1,
"onHoldStatus": {
"onHold": false,
"reason": null
},
"bank": "SEB1234567890",
"dueDate": "2024-01-25T00:00:00Z",
"cardNumber": "**** **** **** 1234",
"invoiceRef": "INV-2024-001",
"invoiceNumber": "INV-2024-001",
"invoiceDate": "2024-01-15T00:00:00Z",
"externalVoucherNumber": "EXT-12345",
"externalVoucherInformation": "Successfully exported to external system",
"externalVoucherErrorInformation": null,
"externalVoucherId": "ext-voucher-550e8400-e29b-41d4-a716-446655440000",
"reminderSentToUser": false,
"employeeId": "EMP001",
"validationErrors": [
{
"errorMessage": "Required field: Description",
"errorCode": "REQUIRED_FIELD",
"checkType": "BLOCKER",
"property": "description",
"expenseRecordId": "550e8400-e29b-41d4-a716-446655440001"
}
],
"reminderSentToApprover": false,
"approverReminded": false,
"hasExpenseViolations": false,
"message": {
"text": "Please attach the receipt for the hotel expense",
"isAdminView": true
},
"hasRejectedExpenseRecords": false,
"hasIncorrectApprovalChains": false,
"approvalAllowed": true,
"currentApproverInfo": {
"approverId": "456e7890-e89b-12d3-a456-426614174999",
"approverName": "Jane Smith",
"approverEmail": "jane.smith@company.com"
},
"sendChain": {
"currentStep": 2,
"totalSteps": 3,
"nextApprover": {
"approverId": "789e0123-e89b-12d3-a456-426614174888",
"approverName": "Bob Johnson",
"approverEmail": "bob.johnson@company.com"
}
},
"tag": {
"simulatedCardReport": false,
"integrationTest": false,
"dimensions": {
"project": "PROJ-001",
"department": "Sales"
}
},
"customFields": [
{
"fieldDefinitionId": "2b965c866b634698811dabf45a491089",
"value": true
}
]
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
The unique identifier of the organization. String, UUID format (32-character hexadecimal). Required. UUID without dashes (32-character hex string)
^[0-9a-fA-F]{32}$"05b8daba9ba14a49846fe77883248cf0"
The id of the expense report to retrieve UUID without dashes (32-character hex string)
^[0-9a-fA-F]{32}$Query Parameters
Action to perform on the expense report instead of a field update. String, enum. Optional. Accepted values: reviewOk, clearTransactions, approve, reject, simulateBilling, sendReminder, setStatus, moveToNextStep, forwardToApprovalOrBooking, deleteExternalVoucherInfo, delete.
approve and reject submit an approval decision for the report's approval chain and require a request body holding approvalChainId. approve carries the per record decisions, so partial approvals are supported; reject rejects every expense record of the report unless explicit records are supplied.
simulateBilling assigns a generated billing file reference to the report and to its card transactions, sets the due date to tomorrow and renames the report. It requires the adminApiExpenseReports:updateExpenseReport-simulateBilling permission and is intended as a developer and support tool.
sendReminder reminds the owner of the report about it and takes an optional message in the request body. It requires the adminApiExpenseReports:updateExpenseReport-sendReminder permission, and only reports that carry an invoice reference can be reminded.
setStatus moves the report to the status given in the request body. Changing the status of several reports at once, and moving reports to another recipient, is a separate operation: PUT /organizations/{organizationId}/reports?action=setStatus.
deleteExternalVoucherInfo clears the external voucher reference from the report and from every expense record in it. With recipientId in the request body, the voucher numbers of that recipient's step in the send chain are cleared as well and a change log entry is written; without it, only the report and its records are cleared. A recipient of another organization is answered with 400 and nothing is cleared.
delete soft-deletes the report: the report and every expense record in it are moved to status DELETED, the report's approval chains are removed and a DELETED change log entry is written. Nothing is removed from the database. Unlike the other actions this one answers 204 with no body, because a deleted report is no longer returned by the read endpoints. It is idempotent - deleting an already deleted report answers 204 as well - and it has no status or report-type restriction, matching what the admin UI allows today. It needs no permission of its own beyond access to the report, the same as reviewOk, clearTransactions, approve, reject and setStatus.
moveToNextStep and forwardToApprovalOrBooking advance the report in its send chain. Both are restricted to the developer role and answer 403 for anyone else. Use PUT /organizations/{organizationId}/reports?action=moveToNextStep to advance several reports at once.
reviewOk, clearTransactions, approve, reject, simulateBilling, sendReminder, setStatus, moveToNextStep, forwardToApprovalOrBooking, deleteExternalVoucherInfo, delete Body
- Option 1
- Option 2
- Option 3
Fields that can be updated on an expense report. Any other fields in the request body are silently ignored.
The display name of the expense report. String, maximum 255 characters.
Comment on the expense report. String, unlimited characters. When action=approve or action=reject is used, this is instead stored as the comment on the approval decision.
Array of custom field values to set on the expense report. Each item must include a fieldDefinitionId and a value. Array of custom field objects.
Target lifecycle status of the report, case insensitive. String. Required when action=setStatus, ignored otherwise. Accepted values are NEW, NORMAL, READY_TO_SEND, SENT and PAID; any other value, known lifecycle status or not, is rejected with 400 INVALID_PARAMETER, since the remaining statuses are reached through their own processing. The transition itself is not validated - the report is moved to the given status whatever its current one is, so the caller decides what makes sense.
External voucher number to store on the report and its expense records. String, unlimited characters. Optional, only used with action=setStatus.
Error information to store on the report; the previous error status is cleared first. String, unlimited characters. Optional, only used with action=setStatus.
Accounting booking date of the report, the date the report is booked on. Stored on the report itself and used when reports are exported and sorted by booking date. String, date-time format. Optional, only used with action=setStatus for the SENT and PAID statuses. When omitted it defaults to the current time: always on a move to SENT, and on a move to PAID only when the report has no booking date yet.
Date the report was handed over to booking. Stored separately from bookingDate and passed on to the integration in the send chain payload. String, date-time format. Optional, only used with action=setStatus for the SENT and PAID statuses, and defaults the same way as bookingDate.
Paid date to store on the report. String, date-time format. Optional, only used with action=setStatus for the PAID status; defaults to the current time when the status changes.
Message sent to the report owner when the report is returned to the user. String, unlimited characters. Optional, only used with action=setStatus. Supplying it is enough to treat the change as a return to the owner when the target status is NEW or NORMAL, returnToUser does not have to be set as well.
Marks the status change as a return to the report owner. Boolean. Optional, only used with action=setStatus. Set it to notify the owner for any target status, or when moving to NEW or NORMAL without a messageText. It is redundant when messageText is given together with the NEW or NORMAL status, which already counts as a return.
Id of the approval chain the decision applies to. String, UUID format (32-character hex). Required when action=approve or action=reject, ignored otherwise. Must belong to the report in the path.
^[0-9a-fA-F]{32}$Expense records to reject. Array of objects, optional. Only used with action=approve or action=reject. Every record of the report that is not listed here is approved, so an omitted or empty list approves the whole report; with action=reject an omitted list rejects every record of the report.
Hide child attributes
Hide child attributes
Id of the expense record to reject. String, UUID format (32-character hex). Required. Must belong to the report in the path.
^[0-9a-fA-F]{32}$Comment explaining why the record was rejected. String, unlimited characters. Optional.
Ids of the approvers to use for the next approval step. Array of strings, optional. Only relevant for action=approve when the approval section requires next step approvers to be chosen; the ids must be approver candidates of the next approval step.
Id of an approver. String, UUID format (32-character hex).
^[0-9a-fA-F]{32}$Response
OK
Hide child attributes
Hide child attributes
NEW, NORMAL, APPROVAL, APPROVED, REJECTED UUID without dashes (32-character hex string)
^[0-9a-fA-F]{32}$UUID without dashes (32-character hex string)
^[0-9a-fA-F]{32}$UUID without dashes (32-character hex string)
^[0-9a-fA-F]{32}$UUID without dashes (32-character hex string)
^[0-9a-fA-F]{32}$UUID without dashes (32-character hex string)
^[0-9a-fA-F]{32}$UUID without dashes (32-character hex string)
^[0-9a-fA-F]{32}$Date when the expense report was paid. ISO-8601 format (e.g., 2024-01-15T10:30:00Z). Read-only.
Date when the expense report was approved. ISO-8601 format (e.g., 2024-01-15T10:30:00Z). Read-only.
APPROVAL, APPROVED, READY_TO_SEND, BULK_TRANSFER, ERROR, NEW, NORMAL, ON_HOLD, PAID, REJECTED, SEND, SENT, TRANSFER, TRANSFER_TO_RECIPIENT, REVIEW DRAFT, PROCESSING, PROCESSED, REJECTED AUTOMATIC, MANUAL, COMPANY_CARD First name of the expense report owner
Last name of the expense report owner
Error information from admin operations
Review type for the organization. None, before approval, or after approval. The AFTER_SEND value actually means before approval.
NONE, AFTER_SEND, AFTER_APPROVAL Number of expense records in this report
Total amount of all expense records in the report
On-hold status information
Hide child attributes
Hide child attributes
List of cards missing configuration
List of expense record IDs with authorization status transactions
Whether all transactions are eligible for manual clearing
Bank information for payment
Payment due date. ISO-8601 format (e.g., 2024-01-15T10:30:00Z).
Card number (masked)
Invoice reference
Invoice number
Invoice date. ISO-8601 format (e.g., 2024-01-15T10:30:00Z).
External voucher number from integration
External voucher information
Error information from external voucher system
External voucher ID
Whether a reminder has been sent to the user
Whether any expense in the report has an unhandled policy violation (duplicate receipt or other)
The latest direct message of the report, used for the message icon in the report list. Always returned when the report has a message, omitted otherwise. Use the 'meta.messages' include to get the report's messages (on the single-report endpoints only the messages sent to the report owner).
Whether an approver has been reminded
Deprecated, use approverReminded. Whether an approver has been reminded
Employee ID (included when 'employeeId' is in include parameter)
Validation errors of the report and of its expenses (included when 'validationErrors' is in include parameter). Errors on an expense carry the expenseRecordId of that expense; errors on the report itself have no expenseRecordId.
Hide child attributes
Hide child attributes
Translated, human-readable text of the error
Code of the error, for example REQUIRED_FIELD
Severity of the error. ERROR - the document cannot be saved, BLOCKER - the report cannot be sent, WARNING - informational only
ERROR, BLOCKER, WARNING The field the error applies to, or the custom field definition id for custom fields. Omitted when the error is not tied to a field.
The expense the error belongs to. Omitted for errors on the report itself.
Whether the report has rejected expense records (included when 'approvalChain' is in include parameter)
Whether the report has incorrect approval chains (included when 'approvalChain' or 'sendChain' is in include parameter)
Whether approval is allowed for this report (included when 'approvalChain' is in include parameter)
Information about the current approver (included when 'approvalChain' is in include parameter)
Hide child attributes
Hide child attributes
Whether the report has a single approver
Whether the report has incorrect approval chains
The approval chain ID
Full name of the current approver
Email address of the current approver
Send chain information (included when 'sendChain' is in include parameter)
Hide child attributes
Hide child attributes
Whether every active step in the chain has been sent
List of senders in the chain
Hide child attributes
Hide child attributes
Status of this step in the chain. The step a report is currently waiting on is the one with the lowest sortOrder among the steps still in TRANSFER_TO_RECIPIENT, which is what the recipientId filter matches on.
Position of this step in the chain, ascending
Whether this step collects the report instead of sending it on
The per expense record send instances belonging to this step
Hide child attributes
Hide child attributes
External id of the record send instance
The expense record this instance belongs to
Voucher number the recipient booked the record under
The recipient's own id for the voucher
Link to the voucher in the recipient system
Message returned by the recipient for this record
Error returned by the recipient for this record
When the recipient booked the record
Whether the record was part of what was sent to the recipient
Unique voucher numbers
Number of non-booked expenses
Number of booked expenses
Aggregated voucher numbers
Aggregated voucher information
Aggregated voucher error information
Server-computed metadata for the report. Each property is opt-in through the include parameter.
Hide child attributes
Hide child attributes
AI review guidance for the report, produced by the Controller agent and rolled up from the verdicts on the report's expenses. Only present when 'meta.autoApproval' is in the include parameter, the feature is enabled for the organization, and the agent has reached a verdict for every expense in the report.
Hide child attributes
Hide child attributes
The verdict for the whole report. APPROVED means the report is low risk and needs no manual attention. REJECTED means at least one of its expenses was flagged and the report needs manual review - no rejection has taken place and the report's own status is unaffected. The two values match the per-expense verdict the expense API already exposes under meta.autoApproval, so a client can use one mapping for both. A report the agent has not finished with is omitted entirely rather than reported as pending.
APPROVED, REJECTED Why the agent reached that verdict, in the same wording the approver app shows the end user and already translated for the caller's locale. For REJECTED these are the deviations found on the report's expenses, de-duplicated across them and ordered by reason code. For APPROVED these are the checks that came back clean. Omitted when there is nothing to show, so a REJECTED report can arrive without it.
Hide child attributes
Hide child attributes
The check the agent ran. The set is closed and matches the agent's reason types; new codes are only added together with a new agent capability.
SIMILAR_REJECTED_ORG, SIMILAR_REJECTED_PERSON, SIMILAR_REJECTED_GLOBAL, POLICY_FAILURE, NOT_VALID_RECEIPT, DEVIATING_AMOUNT_ORG, DEVIATING_AMOUNT_PERSON, DEVIATING_AMOUNT_GLOBAL, PREDICT_AMOUNT_DEVIATION, WEEKEND_PURCHASE_DATE, SPECIAL_ITEM_ALCOHOL, SPECIAL_ITEM_TOBACCO The translated sentence shown for that reason.
curl --request PUT \
--url https://stage-api.findity.com/api/v1/admin/organizations/{organizationId}/reports/{reportId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Business Trip Stockholm",
"comment": "Updated comment for the expense report",
"expenseRecords": [
{
"id": "a73efe636a4d47359f3c28c3024b6d23"
}
],
"customFields": [
{
"fieldDefinitionId": "2b965c866b634698811dabf45a491089",
"value": true
}
]
}
'{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Business Trip Stockholm",
"personId": "123e4567-e89b-12d3-a456-426614174000",
"organizationId": "550e8400-e29b-41d4-a716-446655440001",
"dateCreated": "2024-01-15T09:30:00Z",
"lastUpdated": "2024-01-16T14:45:00Z",
"reportNumber": "ER-2024-001",
"comment": "Business trip to Stockholm for client meeting",
"emailRecipients": "manager@company.com;finance@company.com",
"status": "APPROVED",
"processStatus": "PROCESSED",
"type": "MANUAL",
"reimbursement": 2580.5,
"reimbursementCurrency": "SEK",
"sent": "2024-01-16T10:00:00Z",
"paid": "2024-01-18T00:00:00Z",
"approved": "2024-01-17T15:30:00Z",
"previewUrl": "https://expense.findity.com/api/expensereports/550e8400-e29b-41d4-a716-446655440000",
"meta": {
"autoApproval": {
"status": "REJECTED",
"reasons": [
{
"reason": "POLICY_FAILURE",
"description": "Violates the company's expense policy."
},
{
"reason": "WEEKEND_PURCHASE_DATE",
"description": "The purchase was made during a weekend."
}
]
}
},
"expenseRecords": [
{
"id": "rec1-550e8400-e29b-41d4-a716-446655440000",
"status": "APPROVED",
"personId": "123e4567-e89b-12d3-a456-426614174000",
"organizationId": "550e8400-e29b-41d4-a716-446655440001",
"categoryId": "cat1-550e8400-e29b-41d4-a716-446655440000",
"expenseReportId": "550e8400-e29b-41d4-a716-446655440000",
"dateCreated": "2024-01-15T09:30:00Z",
"lastUpdated": "2024-01-16T14:45:00Z",
"reimbursement": 1250,
"reimbursementCurrency": "SEK",
"rejectComment": null,
"meta": {
"categoryIconUrl": "https://expense.findity.com/api/resources/8a5f867e9b204742a8cc2ca2b6c57358"
}
},
{
"id": "rec2-550e8400-e29b-41d4-a716-446655440000",
"status": "APPROVED",
"personId": "123e4567-e89b-12d3-a456-426614174000",
"organizationId": "550e8400-e29b-41d4-a716-446655440001",
"categoryId": "cat2-550e8400-e29b-41d4-a716-446655440000",
"expenseReportId": "550e8400-e29b-41d4-a716-446655440000",
"dateCreated": "2024-01-15T18:45:00Z",
"lastUpdated": "2024-01-16T14:45:00Z",
"reimbursement": 1330.5,
"reimbursementCurrency": "SEK",
"rejectComment": null,
"meta": {
"categoryIconUrl": "https://expense.findity.com/api/resources/9b6f977f8c305753b9dd3db3c7d68469"
}
}
],
"ownerName": "John Doe",
"firstName": "John",
"lastName": "Doe",
"organizationName": "Acme Corporation",
"organizationNumber": "556123-4567",
"organizationLanguage": "en",
"organizationUseNewDimensions": true,
"organizationRequiresAttestation": false,
"organizationUsesPaymentBasis": true,
"expenseRecordCount": 2,
"totalAmount": 2580.5,
"userCanModifyReports": true,
"userCanSendReports": true,
"reportGroup": 1,
"onHoldStatus": {
"onHold": false,
"reason": null
},
"bank": "SEB1234567890",
"dueDate": "2024-01-25T00:00:00Z",
"cardNumber": "**** **** **** 1234",
"invoiceRef": "INV-2024-001",
"invoiceNumber": "INV-2024-001",
"invoiceDate": "2024-01-15T00:00:00Z",
"externalVoucherNumber": "EXT-12345",
"externalVoucherInformation": "Successfully exported to external system",
"externalVoucherErrorInformation": null,
"externalVoucherId": "ext-voucher-550e8400-e29b-41d4-a716-446655440000",
"reminderSentToUser": false,
"employeeId": "EMP001",
"validationErrors": [
{
"errorMessage": "Required field: Description",
"errorCode": "REQUIRED_FIELD",
"checkType": "BLOCKER",
"property": "description",
"expenseRecordId": "550e8400-e29b-41d4-a716-446655440001"
}
],
"reminderSentToApprover": false,
"approverReminded": false,
"hasExpenseViolations": false,
"message": {
"text": "Please attach the receipt for the hotel expense",
"isAdminView": true
},
"hasRejectedExpenseRecords": false,
"hasIncorrectApprovalChains": false,
"approvalAllowed": true,
"currentApproverInfo": {
"approverId": "456e7890-e89b-12d3-a456-426614174999",
"approverName": "Jane Smith",
"approverEmail": "jane.smith@company.com"
},
"sendChain": {
"currentStep": 2,
"totalSteps": 3,
"nextApprover": {
"approverId": "789e0123-e89b-12d3-a456-426614174888",
"approverName": "Bob Johnson",
"approverEmail": "bob.johnson@company.com"
}
},
"tag": {
"simulatedCardReport": false,
"integrationTest": false,
"dimensions": {
"project": "PROJ-001",
"department": "Sales"
}
},
"customFields": [
{
"fieldDefinitionId": "2b965c866b634698811dabf45a491089",
"value": true
}
]
}
