> ## Documentation Index
> Fetch the complete documentation index at: https://docs.streamlinedpayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Collect a deposit

> Ask a customer for money before an invoice exists, then apply it to the invoice once you issue one.

Use a deposit link to collect money up front, before work starts or goods ship, when there's no invoice to pay yet. You send the customer a link, they pay by card or bank debit, and the money waits as an unapplied payment until you apply it to an invoice.

A deposit has two separate questions, and the API answers each one:

| Question | Field |
| - | - |
| Has the customer paid? | `status` |
| Is the money on an invoice yet? | `applied` |

`paid` with `applied: false` is normal. It's where a deposit sits between the customer paying and you issuing the invoice.

## The lifecycle

```mermaid theme={null}
flowchart LR
  open -->|card| paid
  open -->|bank debit| processing
  processing --> paid
  processing -->|debit returned| open
  paid -->|apply to invoice| applied["paid, applied: true"]
  open --> canceled
  open --> expired
  paid -->|attached payment removed| open
  paid --> refunded
```

| `status` | Means | Webhook |
| - | - | - |
| `open` | The link can be paid. | |
| `processing` | The customer confirmed a bank debit. It settles in 2 to 4 business days. | `deposit_link.processing` |
| `paid` | The money arrived. | `deposit_link.paid` |
| `canceled` | You canceled the link. | `deposit_link.canceled` |
| `expired` | The link passed `expires_at` unpaid. | `deposit_link.expired` |
| `refunded` | The money went back to the customer. | `deposit_link.refunded` |
| `failed` | The link can't be paid. Create a new one. | |

`paid` isn't always final:

* If a bank debit is returned, you get `deposit_link.payment_failed`, and the link goes back to `open` so the customer can try again on the same URL. If its expiry has passed, it becomes `expired` instead.
* If a payment attached to the link by hand is taken off again, usually because it was the wrong one, you get `deposit_link.payment_removed` and the link is `open` again.

Act on `paid`, and undo what you did if one of these follows.

## 1. Create the link

```bash theme={null}
curl https://api.staging.streamlinedpayments.com/api/v1/deposit_links \
  -X POST \
  -H "X-App-Id: $STREAMLINED_APP_ID" \
  -H "X-Api-Key: $STREAMLINED_API_KEY" \
  -H "Idempotency-Key: po-4821-deposit" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_uuid": "c1f0a92b-4d63-4e88-b0a7-2f9e4c6d1b35",
    "amount": 250000,
    "currency": "USD",
    "description": "50% deposit",
    "reference": "PO-4821"
  }'
```

```json theme={null}
{
  "uuid": "3b8e5f21-7a44-4c19-9e02-1d5c7b3a6f08",
  "status": "open",
  "amount": 250000,
  "currency": "USD",
  "url": "https://app.streamlinedpayments.com/d/dep_7K3M9QP2ATX4",
  "short_url": "https://s9d.cc/dep_7K3M9QP2ATX4",
  "expires_at": "2026-11-26T14:22:05Z",
  "reference": "PO-4821",
  "applied": false,
  "apply_to_invoice_uuid": null,
  "payment": null,
  "...": "..."
}
```

Send the customer `short_url`, or `url` if `short_url` is null. Send an `Idempotency-Key` so a retried request returns the same link instead of a second one. See [Create deposit link](https://docs.streamlinedpayments.com/api-reference/deposit-links/create-deposit-link.md).

## 2. Hear when it's paid

[Register a webhook endpoint](https://docs.streamlinedpayments.com/guides/webhooks.md) for `deposit_link.paid` and the other deposit events. Each event carries the link as [Retrieve deposit link](https://docs.streamlinedpayments.com/api-reference/deposit-links/retrieve-deposit-link.md) returns it, so you can read `status`, `paid_at` and `payment` straight from it.

Money can also arrive outside the link, as a wire, ACH credit, or check. When it's matched to the link, the link turns `paid` the same way. `payment.attached_by` tells you how: `null` if the customer paid through the link, `merchant` if someone on your team attached it, or `auto_match` if Streamlined matched it. `payment.amount` is what actually arrived, which can differ from what you asked for.

> [!WARNING]
>
> `auto_match` is an inference from the amount, customer, and currency, and it can be wrong. Before you ship goods or start work on an `auto_match` payment, confirm it with your team or wait for `merchant`.

## 3. Apply it to the invoice

Once you've issued the invoice, put the deposit against it:

```bash theme={null}
curl https://api.staging.streamlinedpayments.com/api/v1/deposit_links/3b8e5f21-7a44-4c19-9e02-1d5c7b3a6f08/invoice \
  -X PUT \
  -H "X-App-Id: $STREAMLINED_APP_ID" \
  -H "X-Api-Key: $STREAMLINED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "invoice_uuid": "8d2c4a17-6b3e-4f95-a1d0-7e9c5b2f4a63" }'
```

The invoice must be for the same customer, in the same currency, and not voided.

* **`paid`**: the money is applied now. You get `200` with `applied: true`, and `payment.invoice_identifier` names the invoice.
* **`processing`**: the deposit is queued. You get `202` with `apply_to_invoice_uuid` set, and it's applied when the bank debit settles. Until then the invoice shows it as a payment on its way, so automatic charges don't take the same money twice.

Applying is safe to retry. To take a queued deposit back off the invoice, call [Unqueue deposit from invoice](https://docs.streamlinedpayments.com/api-reference/deposit-links/unqueue-deposit-from-invoice.md). Moving a deposit that's already applied is done in the Streamlined app.

A deposit larger than the invoice is applied in full, and the rest stays on the invoice as credit, so the invoice shows `Has Credit`. See [Invoice status and aging](https://docs.streamlinedpayments.com/guides/invoice-status-and-aging.md).

## Cancel a link

[Cancel deposit link](https://docs.streamlinedpayments.com/api-reference/deposit-links/cancel-deposit-link.md) stops an `open` link from taking money. The link is kept, with `status: canceled`, so you can still look it up.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.