Invoice withdraw API
The Invoice withdraw API allows API consumers to programmatically withdraw an invoice from an in-progress routing status and return it to an editable status.
Overview
The Invoice withdraw action endpoint allows external systems and automated middleware to trigger the Withdraw action on an invoice via API. This call pulls an invoice back from an active routing, approval, or rejected state and returns it to an editable status so that Accounts Payable or the requester can make adjustments and resubmit.
This endpoint mirrors the behavior of selecting Withdraw in the Coupa web interface and aligns with action endpoints on invoices such as dispute and withdraw_dispute.
HTTP Method:
PUTRequest Body: None (empty body)
Parent Resource: Invoices API (
/api/invoices)
Endpoint
PUT https://<instance>.coupahost.com/api/invoices/{id}/withdraw
Prerequisites and permissions
To call the invoice withdraw endpoint, the API client or user role must have the following configuration:
| Requirement | Value | Description |
|---|---|---|
| OAuth 2.0 Scope | core.invoice.write | Grants write access to invoice actions. |
| User Permissions |
| Both permissions must be granted to the calling user role. |
| Request Headers |
| Standard authentication and content negotiation headers. |
Eligible statuses and resulting transitions
An invoice must be in an eligible status to be withdrawn. Invoices in terminal states (such as Approved, Void, or Paid) cannot be withdrawn.
Eligible initial statuses:
- Pending Approval (
pending_approval) - Pending Receipt (
pending_receipt) - Rejected (
rejected)
Resulting status based on invoice origin:
| Invoice origin | Status before withdraw | Status after withdraw | Description |
|---|---|---|---|
| Buyer-originated (UI, API, CSV) | Pending Approval, Pending Receipt, Rejected | Draft (draft) | Returns to draft status so the invoice can be edited and resubmitted. |
| Supplier-originated (CSP, cXML, SAN) | Pending Approval, Pending Receipt, Rejected | On Hold (on_hold) | Moves to on hold status for review and resolution. |
Parameters
Path parameters:
| Parameter | Data type | Required | Description |
|---|---|---|---|
id | integer | Yes | The unique Coupa identifier of the invoice record to withdraw. |
There are no query parameters or request body elements required for this call.
HTTP status codes
| HTTP code | Status message | Description |
|---|---|---|
200 | OK | The invoice was successfully withdrawn. The response payload returns the updated invoice object. |
401 | Unauthorized | The access token is invalid, expired, or missing. |
403 | Forbidden | The authenticated caller does not have the required role permissions or OAuth scopes. |
404 | Not Found | The specified invoice ID does not exist or cannot be accessed by the user. |
422 | Unprocessable Entity | The invoice cannot be withdrawn because its current status is not eligible for withdrawal. |
Example cURL request
curl --location --request PUT 'https://<instance>.coupahost.com/api/invoices/98765/withdraw' \
--header 'Authorization: Bearer <access_token>' \
--header 'Accept: application/xml'
Example XML response
HTTP status: 200 OK
<?xml version="1.0" encoding="UTF-8"?>
<invoice-header>
<id type="integer">98765</id>
<invoice-number>INV-2026-0042</invoice-number>
<status>draft</status>
<status-comments nil="true"/>
<invoice-date type="datetime">2026-09-15T00:00:00-07:00</invoice-date>
<net-due-date type="datetime">2026-10-15T23:59:59-07:00</net-due-date>
<currency>
<id type="integer">1</id>
<code>USD</code>
</currency>
<total type="decimal">1250.00</total>
<gross-total type="decimal">1250.00</gross-total>
<tax-amount type="decimal">0.00</tax-amount>
<supplier>
<id type="integer">184</id>
<name>Apex Technology Solutions</name>
<number>SUP-10084</number>
</supplier>
<account-type>
<id type="integer">1</id>
<name>Corporate Chart of Accounts</name>
</account-type>
<created-at type="datetime">2026-09-15T10:14:22-07:00</created-at>
<updated-at type="datetime">2026-09-29T09:45:10-07:00</updated-at>
<created-by>
<id type="integer">742</id>
<email>ap.clerk@example.com</email>
<login>apclerk</login>
</created-by>
<updated-by>
<id type="integer">742</id>
<email>ap.clerk@example.com</email>
<login>apclerk</login>
</updated-by>
<invoice-lines type="array">
<invoice-line>
<id type="integer">182736</id>
<line-num type="integer">1</line-num>
<description>IT Cloud Management Subscription - Q3</description>
<price type="decimal">1250.00</price>
<quantity type="decimal">1.0</quantity>
<total type="decimal">1250.00</total>
<status>draft</status>
<type>InvoiceQuantityLine</type>
<uom>
<id type="integer">1</id>
<code>EA</code>
</uom>
</invoice-line>
</invoice-lines>
</invoice-header>
Example JSON response
HTTP status: 200 OK
{
"id": 98765,
"invoice_number": "INV-2026-0042",
"status": "draft",
"invoice_date": "2026-09-15T00:00:00-07:00",
"total": "1250.00",
"currency": {
"id": 1,
"code": "USD"
},
"supplier": {
"id": 184,
"name": "Apex Technology Solutions",
"number": "SUP-10084"
},
"created_at": "2026-09-15T10:14:22-07:00",
"updated_at": "2026-09-29T09:45:10-07:00"
}
Example error response
HTTP status: 422 Unprocessable Entity
<?xml version="1.0" encoding="UTF-8"?>
<errors>
<error>Could not withdraw Invoice 98765</error>
</errors>