---
title: "Create a Deposit"
description: "Create variable or fixed deposits, redirect to hosted checkout, and retrieve outcomes."
canonical_url: "https://checkout.verify.et/docs/integration"
markdown_url: "https://checkout.verify.et/docs/integration.md"
last_updated: "2026-10-06"
x_farming_labs_generated_preamble: true
---

# Create a Deposit
URL: /docs/integration
LLM index: /llms.txt
Description: Create variable or fixed deposits, redirect to hosted checkout, and retrieve outcomes.
Related: /docs/hosted-checkout, /docs/reconciliation, /docs/api

# Create a hosted checkout deposit

Before calling the API, your workspace needs an active receiving account, an API
key with the required scope, and an active return origin matching `return_url`.

<AgentSkillCard />

## Request

`POST https://checkoutapi.verify.et/v1/deposits`

<Tabs items={["Variable amount", "Fixed amount"]}>
  <Tab value="Variable amount">
    Omit `amount`. The customer enters an allowed ETB amount on checkout.
    ```json
    {
      "merchant_customer_id": "customer_42",
      "currency": "ETB",
      "return_url": "https://shop.example.com/payments/return"
    }
    ```
  </Tab>
  <Tab value="Fixed amount">
    Send `amount` and optionally `payment_method` to limit checkout to one provider.
    ```json
    {
      "merchant_customer_id": "customer_42",
      "amount": "250.00",
      "currency": "ETB",
      "payment_method": "telebirr",
      "return_url": "https://shop.example.com/payments/return"
    }
    ```
  </Tab>
</Tabs>

Amounts may be sent as JSON strings or numbers and are returned as normalized
strings. ETB is the current currency. Provider and amount limits are enforced by
the response options and hosted checkout.

## Response

A successful creation returns `201` with the deposit, a public checkout URL, its
expiry, and the accounts available for this deposit.

```json
{
  "data": {
    "id": "dep_example",
    "merchant_order_id": "order_1042",
    "merchant_customer_id": "customer_42",
    "status": "awaiting_transfer",
    "verification_status": "not_started",
    "notification_status": "not_ready",
    "amount": "250.00",
    "currency": "ETB",
    "checkout_url": "https://checkout.verify.et/c/example_token",
    "support_reference": "VC-1042",
    "payment_options": [
      {
        "payment_method": "telebirr",
        "institution_code": "telebirr",
        "institution_name": "Telebirr",
        "masked_identifier": "09••••1234",
        "min_amount": "1.00",
        "max_amount": "30000.00"
      }
    ],
    "metadata": {},
    "created_at": "2026-08-21T10:00:00.000Z",
    "expires_at": "2026-08-21T11:00:00.000Z"
  },
  "meta": {
    "requestId": "req_example",
    "apiVersion": "2026-06-01"
  }
}
```

Persist `data.id`, then redirect the customer's browser to `data.checkout_url`.
The link expires 60 minutes after creation.

## Recommended production flow

Use signed webhooks for prompt change notifications and the deposits API for the
authoritative current state:

```text
Create checkout
      ↓
Save deposit ID
      ↓
Customer completes payment
      ↓
Signed webhook informs merchant backend
      ↓
Merchant fetches deposit by ID when confirmation is needed
      ↓
Merchant fulfills only when current status is succeeded
```

The webhook tells your backend that something changed; it is not a replacement
for storing the deposit ID or retrieving the current deposit. Webhooks are
delivered at least once and may be delayed, retried, duplicated, or arrive out of
order. Verify the webhook signature over the raw body, deduplicate by event ID,
then use `GET /v1/deposits/{depositId}` whenever you need to confirm the latest
state.

Only `succeeded` authorizes fulfillment. Treat `review_required` as pending an
operational decision, and never fulfill `failed`, `expired`, or `cancelled`.
Apply fulfillment exactly once using the Verify Checkout deposit ID as the
idempotency key in your own system.

## Retrieve and reconcile

- `GET /v1/deposits/{depositId}` — retrieve the current authoritative state.
- `GET /v1/deposits` — list deposits using the documented filters and pagination.
- `GET /v1/deposits/{depositId}/events` — inspect the deposit event timeline.

Use [signed webhooks](/docs/webhooks) for prompt automation and polling as a
recovery path. The public API does not require you to build a manual checkout or
accept payment references in your own frontend.

## Error envelope

```json
{
  "data": null,
  "error": {
    "code": "return_url_not_allowed",
    "message": "The return URL is not allowed"
  },
  "meta": { "requestId": "req_example" }
}
```

Branch on the stable `error.code`, show your own customer-safe message, and log
`meta.requestId`. See the generated [API reference](/docs/api) for every field,
filter, status, and error.

## Sitemap

Sitemap discovery is not enabled for this deployment.
