---
title: "Paused transfers"
description: "Upload documents and resume a transfer that waits for a supporting document, sender details or a limit decision."
---
Gravv accepts some transfers that cannot go ahead yet. For example, the bank needs an invoice, the payout route needs the sender's date of birth, or the amount is over a limit. Gravv does not refuse these transfers. It returns HTTP 200 with `transfer_status` `paused`, lists what it needs in `requirements`, and waits. You send what it needs with [`POST /v1/transfer/{id}/resume`](/api-reference/transfer/post-v1-transfer-id-resume).

**Example.** A company sends 4,800.00 USD by SWIFT to a contractor in Abuja without a document. The response is `paused`, with `pause_reason` `supporting_document_required` and `expires_at` 72 hours later. The company uploads the service contract and resumes the transfer with the document's id. The payout goes ahead, and Gravv does not charge the fee again. If the company had done nothing, the transfer would have failed at `expires_at` and Gravv would have refunded the fee.

## Read the pause

```json title="Paused transfer response"
{
  "data": {
    "amount": "4800",
    "amount_currency": "USD",
    "reference": "c1a2b3c4-d5e6-4f70-8a91-b2c3d4e5f607",
    "date_created": "2026-10-13T10:02:11.000Z",
    "transfer_status": "paused",
    "transaction_id": "0e1f2a3b-4c5d-4e6f-8a7b-9c0d1e2f3a4b",
    "local_amount": null,
    "local_currency": null,
    "fee": "25",
    "fee_currency": "USD",
    "requires_approval": false,
    "status": "awaiting_supporting_document",
    "park_reason": "supporting_document",
    "pause_reason": "supporting_document_required",
    "requirements": [
      {
        "type": "supporting_document",
        "description": "resume with supporting_document_ids: at least one supporting document for this payout"
      }
    ],
    "expires_at": "2026-10-16T10:02:11Z"
  },
  "error": null
}
```

| Field | Meaning |
| :-- | :-- |
| `pause_reason` | Why it paused: `per_transfer`, `daily`, `weekly`, `monthly`, `annual`, `annual_requires_approval` (a limit), `screening`, `sender_details_required` or `supporting_document_required` |
| `requirements[]` | What to send. `type` is the field or action. `levels` lists the verification levels Gravv accepts |
| `breached_window`, `remaining_usd` | For a limit pause, the window the transfer exceeded and what is left in it, in USD |
| `expires_at` | When the pause ends, by default 72 hours after the pause. The transfer then fails, and Gravv returns the amount and fee |

Gravv also sends the pause as the webhook `transfer.requires_information` (`event_data.status` `paused`, `reason`, and `limit_details` with the requirements). A document pause can also start later, shortly before the payout, if the bank's requirement changed. In that case you get only the webhook. Store `reference`, because it is the id you resume.

## What each requirement asks for

| `requirements[].type` | Resume with |
| :-- | :-- |
| `supporting_document` | `supporting_document_ids`, and nothing else |
| `remitter_full_name`, `remitter_date_of_birth`, `remitter_address`, `remitter_country` | `additional_information` with those fields |
| `customer_email` | Nothing in the body. Add an email to the customer with [`PUT /v1/customers/{customer_id}`](/api-reference/customers/put-v1-customers-customer-id), then resume with `{}` |
| `remitter_verification` | `remitter_verification` at one of the listed `levels` (businesses that verify their own senders) |
| `screening_clear` | `remitter_verification` whose `screening` values are all `clear` |
| `admin_review` | Nothing you can send. Only Gravv can release it. Contact support with the `reference`, or let it expire and send within `remaining_usd` |

Never invent verification details. Send only what you checked.

## Upload a supporting document

Some banks ask for a document on SWIFT payouts, such as an invoice or a contract. Upload it with [`POST /v1/transfer/documents`](/api-reference/transfer/post-v1-transfer-documents), then pass its id on the transfer (`supporting_document_ids`) or on the resume:

```bash title="Upload a document request"
curl --request POST \
     --url https://api.gravv.xyz/v1/transfer/documents \
     --header 'Api-Key: <API_KEY>' \
     --header 'Content-Type: application/json' \
     --header 'Idempotency-Key: 4f8b2d6a-9c1e-4a7b-8e3d-5f6a7b8c9da6' \
     --data '
{
  "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "document_type": "contract",
  "description": "Consulting contract September 2026",
  "file_name": "contract-cz-2026.pdf",
  "content_type": "application/pdf",
  "content": "JVBERi0xLjQKJcfsj6IKMSAwIG9iago8PC9UeXBlL0NhdGFsb2c+PgplbmRvYmoK"
}
'
```

```json title="Upload a document response"
{
  "data": {
    "content_type": "application/pdf",
    "created_at": "2026-10-13T10:05:57.665487Z",
    "description": "Consulting contract September 2026",
    "document_type": "contract",
    "file_name": "contract-cz-2026.pdf",
    "id": "9f4c2e1a-7b3d-4c5e-8f6a-1b2c3d4e5f60",
    "size_bytes": 184233
  },
  "error": null
}
```

Rules for documents:

- `content` is the file as standard base64. The file is a PDF, PNG or JPEG, and `content_type` must match the file itself.
- A file can be at most **700 KB**. In sandbox, keep it **under 500 KB**, because sandbox refuses requests from about 600 KB with a 413 that says 10MB.
- `document_type` is one of `invoice`, `proforma_invoice`, `purchase_order`, `contract`, `receipt`, `bill_of_lading`, `customs_declaration`, `bank_statement`, `proof_of_income`, `tax_document` or `other`. `other` needs a `description` (at most 140 characters).
- Upload the document for the customer who sends the transfer. Each document can belong to one transfer only, and a transfer takes up to 5 documents. Gravv deletes a document that no transfer uses after 7 days.

## Resume the transfer

Send what `requirements` asked for to `POST /v1/transfer/{reference}/resume`. Use a **new `Idempotency-Key` on every attempt**. The resume body is strict. Unlike the transfer request, it refuses any unknown field.

```bash title="Resume with a document request"
curl --request POST \
     --url https://api.gravv.xyz/v1/transfer/c1a2b3c4-d5e6-4f70-8a91-b2c3d4e5f607/resume \
     --header 'Api-Key: <API_KEY>' \
     --header 'Content-Type: application/json' \
     --header 'Idempotency-Key: 7a1c5e9b-2d4f-4b8a-9c6e-0d1e2f3a4bb7' \
     --data '
{
  "supporting_document_ids": [
    "9f4c2e1a-7b3d-4c5e-8f6a-1b2c3d4e5f60"
  ]
}
'
```

```json title="Resume response"
{
  "data": {
    "transfer_id": "c1a2b3c4-d5e6-4f70-8a91-b2c3d4e5f607",
    "status": "approved_awaiting_execution",
    "transfer_status": "pending",
    "resumed": true
  },
  "error": null
}
```

- `resumed: true` means the transfer moves on. Gravv sends a `transfer.resumed` webhook, then the usual transfer events. `status` names an internal step, so do not build logic on it.
- `resumed: false` with new `requirements` means something is still missing, or the transfer is still over a cap. Send what is listed, with another new key.

For a sender-details pause, send the missing fields:

```bash title="Resume with sender details request"
curl --request POST \
     --url https://api.gravv.xyz/v1/transfer/3019b5b3-1ad0-4f00-809a-8e52f727ba0d/resume \
     --header 'Api-Key: <API_KEY>' \
     --header 'Content-Type: application/json' \
     --header 'Idempotency-Key: 1c6e0a4d-8b2f-4e9c-a7d1-2e3f4a5b6cc8' \
     --data '
{
  "additional_information": {
    "remitter_date_of_birth": "1988-04-17",
    "remitter_address": {
      "address_line1": "27 Ashburnham Road",
      "city": "London",
      "postal_code": "SW10 0PL",
      "country": "GB"
    }
  }
}
'
```

To avoid a sender-details pause, send `additional_information` on the transfer itself. Gravv uses its fields ahead of the customer profile.

## What can go wrong

| Response | Why | Fix |
| :-- | :-- | :-- |
| 400 `this transfer is paused for a supporting document: resume it with supporting_document_ids only, without remitter_verification or additional_information` | Extra fields on a document pause | Send only `supporting_document_ids` |
| 400 `invalid request body: json: unknown field "documents"` | A field the resume does not know | Use the exact field names |
| 400 `this transfer is not paused` (with `transfer_status`) | Already resumed, failed or completed | Read the transaction |
| 400 `remitter_date_of_birth must be a date as YYYY-MM-DD` | Wrong date format | Send `1988-04-17` |
| 400 `the remitter information does not match the sender this transfer was paused for; resume with the same remitter_id, or initiate a new transfer` | A different `remitter_id` | Use the same one, or start a new transfer |
| 400 `supporting_document_ids: each id must be a document uploaded for this customer and not used by another transfer` | Wrong customer, already used, or older than 7 days | Upload it again for the sending customer |
| 400 `content: the file is not a application/pdf` | `content_type` does not match the file | Send the real type |
| 400 `content: the file is 812 KB (831488 bytes); the largest accepted is 700 KB (716800 bytes). …` | The file is over 700 KB | Compress it to 700 KB or less |
| 413 `the uploaded file is too large — the maximum is 10MB` | In sandbox, a request from about 600 KB, whatever the message says. In live, a file over about 10 MB | Compress it: under 500 KB in sandbox, 700 KB or less in live |
| 422 `ERROR_CODE_SUPPORTING_DOCUMENT_REQUIRED` | You resumed with an empty list. Or document pauses are switched off and you sent a transfer without a required document | Upload, then resume (or send again) with the id and a new key |
| 422 `transfers are not permitted for this sender` (`ERROR_CODE_SUBJECT_BLOCKED`) | The sender is blocked | Contact support. Do not retry |
| 410 `ERROR_CODE_TRANSFER_PAUSE_EXPIRED` | Past `expires_at`. The transfer failed and Gravv refunded it | Start a new transfer with what was missing |
| 410 `ERROR_CODE_TRANSFER_PAUSE_CANCELLED` | Gravv cancelled the pause | Start a new transfer |
| 409 `the paused transfer changed while this request ran; please retry` | Two resumes at once | Retry once with a new key |
| 404 `transfer workflow not found` | The id is the `transaction_id`, or another business's transfer | Use the transfer `reference` |
| 400 `insufficient balance` on resume | The balance was spent while paused | Fund the account, then resume with a new key |
| 503 `transfer limits are temporarily unavailable, please retry` | Gravv cannot check limits right now | Retry with backoff |

When a pause ends before you resume the transfer, Gravv sends `transfer.status.failed` with `event_data.reason` `supporting_document_expired`, `sender_details_expired` or `limit_pause_expired` (or the `_cancelled` forms).

## Testing in sandbox

In sandbox you can test uploads and the resume checks, such as wrong ids, extra fields and the size limit. A real pause depends on the bank's setting for the account, the payout route and your limits policy. You cannot force one with a test value.

Related: [Transfer limits](/platform/transfers/transfer-limits), and the recipes [SWIFT with a document pause](/recipes/bank-payouts/pay-a-person-abroad-by-swift), [Stay within transfer limits](/recipes/bank-payouts/stay-within-transfer-limits) and [Send money to Ghana](/recipes/remittance-and-crypto/send-money-to-ghana).
