# Stamps (/stamps)

Procure e-stamps — order, track, and download stamp PDFs, and reserve them into Esign flows.



The Stamp APIs let you procure e-stamps and attach them to signing flows.
You look up the supported states and articles, place a procurement order,
poll until the stamps are issued, and then either download the stamp PDFs
or reserve them into an Esign session — where the stamp pages are prefixed
to your document before signing starts.

All stamp endpoints live under `/api/v1/stamps` and use the same base URLs
and `Authorization: Bearer YOUR_ACCESS_TOKEN` header as the rest of the API.

## How stamping works [#how-stamping-works]

1. [List state codes](/api-reference/stamps/listStateCodes) and
   [List articles](/api-reference/stamps/listArticles) to find the
   `state_code` and `article_id` you need.
2. [Create a stamp order](/api-reference/stamps/createStampOrder) with the
   party names, duty amount, and quantity.
3. Poll [Get order status](/api-reference/stamps/getStampOrderStatus) (or
   [List stamp orders](/api-reference/stamps/listStampOrders)) until the
   stamps become `available`.
4. [Download the stamp PDF](/api-reference/stamps/downloadStampPdf), or
   reserve the stamps into an Esign session (see below).

## 1. Find the state and article [#1-find-the-state-and-article]

Article IDs are per-state — fetch the article list for your state first:

```bash
curl --location 'https://esign-api-v2.surepass.app/api/v1/stamps/articles?state_code=AN' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
```

```json
{
  "data": [
    {
      "article_id": "2337",
      "article_code": "AFFIDAVIT",
      "article_name": "Affidavit"
    }
  ],
  "status_code": 200,
  "message": "Success",
  "success": true
}
```

## 2. Create a procurement order [#2-create-a-procurement-order]

```json title="POST /api/v1/stamps/create-order"
{
  "state_code": "AN",
  "first_party_name": "Alice Test",
  "second_party_name": "Bob Test",
  "article_id": "2337",
  "stamp_duty_amount": 10,
  "consideration_amount": 1000.0,
  "quantity": 1
}
```

The call is **asynchronous** — a successful response returns the order with
an empty `stamps` array while procurement runs in the background. Billing
charges `estamp_duty` (`stamp_duty_amount × quantity`) plus `estamp_fees`
(one per stamp); the request fails with `402` if the wallet balance is
insufficient.

Constraints: `stamp_duty_amount` must be a whole number (max 1,000,000),
`quantity` between 1 and 5000, party names up to 200 characters.

## 3. Track the order [#3-track-the-order]

Poll [Get order status](/api-reference/stamps/getStampOrderStatus) with the
order `client_id` (`stamp_...`). Once procurement completes, `stamps`
contains the issued instances and `status_counts` is populated:

```json
{
  "data": {
    "client_id": "stamp_pkHLyIzspuMWBMXizUSc",
    "status_counts": {
      "pending": 0,
      "available": 1,
      "reserved": 0,
      "used": 0,
      "rejected": 0
    },
    "stamps": [
      {
        "stamp_id": "stamp_inst_uNeOUwjMVGNFexnxFSCP",
        "status": "available"
      }
    ]
  },
  "status_code": 200,
  "message": "Success",
  "success": true
}
```

Each stamp instance moves through these statuses:

| Status      | Meaning                                   |
| ----------- | ----------------------------------------- |
| `pending`   | Procurement is not completed yet          |
| `available` | Issued and available for use or download  |
| `reserved`  | Temporarily reserved against another flow |
| `used`      | Already consumed                          |
| `rejected`  | Procurement was rejected by the vendor    |

`stamps[].stamp_id` (`stamp_inst_...`) is the public **instance** ID — use
it for downloads and explicit reservation. The order ID (`stamp_...`) is
only for `order-status` and `list`.

## 4. Download the stamp PDF [#4-download-the-stamp-pdf]

[Download stamp PDF](/api-reference/stamps/downloadStampPdf) returns a
short-lived signed URL for a completed (`available`) stamp instance — PDF
bytes are not streamed through the API:

```bash
curl --location 'https://esign-api-v2.surepass.app/api/v1/stamps/download-pdf?client_id=stamp_inst_uNeOUwjMVGNFexnxFSCP' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
```

## Using stamps in an Esign [#using-stamps-in-an-esign]

Stamps can be reserved directly into
[Initialize Esign](/api-reference/esign/initializeEsign) (and
[Initialize Esign from template](/api-reference/templates/initializeFromTemplate))
through the `stamp` object. On success, the reserved stamp PDFs are prefixed
to the uploaded document before the signing flow starts.

### Mode 1 — reserve by search [#mode-1--reserve-by-search]

The backend picks matching stamps from your `available` inventory:

```json title="POST /api/v1/esign/initialize-esign (excerpt)"
{
  "file_id": "file_gXvuxRnKgdRWEHAXpnXw",
  "signers": ["..."],
  "stamp": {
    "amount": "30",
    "state_code": "AN",
    "article_id": "2337"
  }
}
```

Optional `first_party_name` / `second_party_name` filters narrow the search
to inventory matching those names.

### Mode 2 — reserve by explicit stamp IDs [#mode-2--reserve-by-explicit-stamp-ids]

Pass the exact instance IDs from `order-status` or `list`; only IDs that are
still `available` are reserved:

```json title="POST /api/v1/esign/initialize-esign (excerpt)"
{
  "file_id": "file_gXvuxRnKgdRWEHAXpnXw",
  "signers": ["..."],
  "stamp": {
    "stamp_instance_ids": [
      "stamp_inst_UZTqKQztUPyvnnjdCzxD",
      "stamp_inst_uNeOUwjMVGNFexnxFSCP"
    ]
  }
}
```

If the requested inventory is not available, initialization fails with
`422` and one of these error codes:

| Message Code                  | Description                                        |
| ----------------------------- | -------------------------------------------------- |
| `stamp_combination_not_found` | No available stamps match the search parameters.   |
| `inventory_conflict`          | Requested stamp instances are no longer available. |
