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

# Standing Deposit Addresses API

> Register immutable deposit instructions, inspect deposits, pause conversion and request refunds.

Base URL: `https://orchestration.flashnet.xyz`. For the end-to-end flow, see [Standing Deposit Addresses](/products/orchestration/standing-deposit-addresses).

All endpoints require a server key in `Authorization: Bearer fn_...`. Client keys are rejected, including on reads. Every mutation requires `X-Idempotency-Key`.

`{ref}` is your customer reference: a string of 1–128 characters, scoped to your partner account. Use the same reference throughout this API, not the returned `standingAddressId`. URL-encode it as one path segment; a simple identifier such as `customer-123-usdc-v1` avoids encoding issues. Keep your own reference-to-customer mapping: this API has no list-all-instructions endpoint.

| Method  | Path                                            | Success                                             |
| ------- | ----------------------------------------------- | --------------------------------------------------- |
| `PUT`   | `/v1/standing-deposit-addresses/{ref}`          | `200`: create or retrieve the identical instruction |
| `GET`   | `/v1/standing-deposit-addresses/{ref}`          | `200`: retrieve current addresses and enabled state |
| `PATCH` | `/v1/standing-deposit-addresses/{ref}`          | `200`: pause or resume                              |
| `GET`   | `/v1/standing-deposit-addresses/{ref}/deposits` | `200`: list observed deposits                       |
| `POST`  | `/v1/standing-deposit-addresses/{ref}/resolve`  | `202`: record a refund request                      |

## Create or retrieve an instruction

`PUT /v1/standing-deposit-addresses/{ref}`

The body defines the destination and conversion policy. Replace the address placeholders before sending:

```json theme={null}
{
  "destination": {
    "chain": "base",
    "asset": "USDC",
    "address": "<recipient-on-Base>"
  },
  "slippageBps": 50,
  "feeBps": 0,
  "affiliateIds": [],
  "refundAddresses": {
    "base": "<refund-recipient-on-Base>"
  }
}
```

| Field                 | Required | Rules                                                                                                                                                                                                                       |
| --------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `destination.chain`   | Yes      | Supported destination chain identifier. Use the route catalog's chain identifier. Hedera destinations are not supported for standing instructions.                                                                          |
| `destination.asset`   | Yes      | Nonempty asset identifier for that destination. Use the catalog's spelling and case.                                                                                                                                        |
| `destination.address` | Yes      | Valid receiving address on the destination chain.                                                                                                                                                                           |
| `slippageBps`         | No       | Integer `0`–`10000`; default `50`. One basis point is 0.01%.                                                                                                                                                                |
| `feeBps`              | No       | Integer `0`–`9999`; default `0`. Sets the instruction's platform-fee floor; the ordinary fee policy resolves per batch.                                                                                                     |
| `affiliateIds`        | No       | Up to 16 registered affiliate entries; default `[]`. See below.                                                                                                                                                             |
| `refundAddresses`     | No       | Source-chain-to-refund-address map; default `{}`. Targets must be valid on their respective chains. These are generated-order refund targets, not an automatic dust-refund policy. Use canonical chain identifiers as keys. |

The body and `destination` object reject unknown fields. Do not include `sourceChain`, `sourceAsset`, `amount`, `enabled`, `appFees`, or an expiration. The server determines available source addresses. Deposits determine conversion amounts.

An affiliate entry is either a registered ID string or an override object:

```json theme={null}
{
  "affiliateIds": [
    "referrer-alice",
    { "affiliateId": "platform-fee", "feeBps": 25 }
  ]
}
```

This fragment belongs inside the full registration body. IDs are trimmed and lowercased, and must match `^[a-z0-9][a-z0-9_-]{0,63}$`. Overrides are integers `1`–`9999`. Resolved affiliate fees must total less than `10000` basis points. Profiles must belong to your partner and have a payout address. Their resolved configuration is frozen into the instruction; subsequent profile changes do not change it. [Register affiliates](/products/orchestration/api/resources#affiliates) first.

### Response

Both creation and identical-instruction retrieval return HTTP `200`:

```json theme={null}
{
  "standingAddressId": "sda_example",
  "addresses": {
    "base": "0x...",
    "solana": "..."
  },
  "enabled": true
}
```

| Field               | Type    | Meaning                                                                                       |
| ------------------- | ------- | --------------------------------------------------------------------------------------------- |
| `standingAddressId` | string  | Stable Orchestra instruction ID.                                                              |
| `addresses`         | object  | Public source-chain identifier to deposit address. Display only returned chain/address pairs. |
| `enabled`           | boolean | Whether the instruction permits new conversions.                                              |

The address map above is illustrative. Available sources depend on configured standing custody and partner/route admission. A chain address may observe multiple supported assets; it does not promise support for arbitrary tokens or every amount. An issued address is published only after deposit observation is acknowledged.

There is no creation-time quote, fixed output, deposit amount or expiry in this response. The destination and fee settings are not returned; store your submitted instruction.

### Immutability and retries

The same partner/reference and normalized instruction return the same standing instruction. Different instructions at the same reference return `409 instruction_conflict`. This includes changes to destination, slippage, fees, affiliate entries and configured refund addresses. A different idempotency key does not permit an instruction change.

For a network timeout, retry with the original body and idempotency key. HTTP idempotency and instruction identity are separate checks: changing omitted defaults to explicit values can conflict with an existing idempotency key even when the resulting instruction would be equivalent. Preserve your original request.

A successful idempotent replay returns the original response with `X-Idempotency-Replayed: true`. Its enabled state or address map may now be stale. Use `GET` for current state. Failed registration can leave a durable instruction awaiting observation setup; retry the same reference and body rather than registering replacements.

## Retrieve current addresses

`GET /v1/standing-deposit-addresses/{ref}`

Returns the same three fields as `PUT`. No idempotency key is required.

Existing addresses remain stable. A current `GET` or an identical `PUT` that is not served from the idempotency cache can add source chains enabled since registration. Treat new map entries as additional addresses; do not replace an existing address with a locally derived value. Retrieval can return a temporary error while new observation setup is unavailable.

## Pause or resume

`PATCH /v1/standing-deposit-addresses/{ref}`

The complete body is:

```json theme={null}
{ "enabled": false }
```

Use `true` to resume. Unknown fields or a missing `enabled` return `400 immutable_instruction`.

Response (`200`):

```json theme={null}
{
  "standingAddressId": "sda_example",
  "enabled": false
}
```

Pause leaves observation active and prevents new source commitments. Already committed transactions can continue recovery. It does not reject incoming blockchain transfers or refund existing deposits. Resume retries work held specifically by `standing_address_paused`; it does not clear unrelated holds or cancel refund requests.

Use a new idempotency key for each intended state change and the same key only to retry that change. There is no delete or instruction-edit endpoint.

## List deposits

`GET /v1/standing-deposit-addresses/{ref}/deposits?limit=50&offset=0`

| Parameter | Rules                             |
| --------- | --------------------------------- |
| `limit`   | Integer `1`–`200`; default `50`.  |
| `offset`  | Nonnegative integer; default `0`. |

Response (`200`), illustrating an unreserved deposit waiting for a sufficient amount:

```json theme={null}
{
  "deposits": [
    {
      "id": "deposit_example",
      "chain": "solana",
      "asset": "USDC",
      "amount": "100000",
      "sourceTxId": "<Solana-transaction-signature>",
      "sourceTxIndex": null,
      "senderAddress": "<Solana-sender-address>",
      "observedAt": "2026-09-08T12:00:00.000Z",
      "status": "below_minimum",
      "code": "xchain_amount_too_small",
      "batchId": null,
      "orderId": null,
      "quoteId": null,
      "batchState": null,
      "refundTxId": null
    }
  ],
  "nextOffset": null
}
```

The amount is illustrative, not a published route minimum.

| Deposit field    | Type           | Meaning                                                                                                                      |
| ---------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `id`             | string         | Stable deposit ID. Deduplicate observations using this value.                                                                |
| `chain`, `asset` | string         | Source chain and asset. `chain` uses stored chain identifiers; aliases may differ from the public address-map keys.          |
| `amount`         | string         | Gross source amount in integer smallest units. Bitcoin uses sats before its claim fee, not the net amount entering the swap. |
| `sourceTxId`     | string         | Source transaction identity.                                                                                                 |
| `sourceTxIndex`  | string or null | Source event index; for Bitcoin, the output index (`vout`). Use it with the transaction hash.                                |
| `senderAddress`  | string or null | Attributed source sender, when available. Not an authorized refund target.                                                   |
| `observedAt`     | string         | Observation timestamp.                                                                                                       |
| `status`         | string         | Order status when an order exists; otherwise the deposit or held/refund batch state.                                         |
| `code`           | string or null | Order error when an order exists; otherwise a batch/deposit reason. Preserve unfamiliar values.                              |
| `batchId`        | string or null | Conversion/refund group. Multiple deposits may share it.                                                                     |
| `orderId`        | string or null | Ordinary order ID, present only after the order exists.                                                                      |
| `quoteId`        | string or null | Quote ID, present only after its snapshot is saved.                                                                          |
| `batchState`     | string or null | Standing allocation state, separate from order progress.                                                                     |
| `refundTxId`     | string or null | Refund transaction ID recorded for this batch, when available. Check ordinary order details when an order exists.            |

Results are newest-first by observation time, then deposit ID. `nextOffset` advances by `limit` when a full page is returned; otherwise it is null. A full final page can be followed by an empty page. Pagination is not a snapshot: deduplicate across shifting pages and revisit recent rows to receive status updates.

### States before order creation

| `status`           | Handling                                                                                                                         |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `pending`          | Observed and awaiting processing. This can persist while the instruction is paused.                                              |
| `processing`       | Reserved for preparation. Keep polling.                                                                                          |
| `below_minimum`    | Too small to convert now. EVM/Solana dust can join a later same-binding, same-asset deposit; Bitcoin outputs remain independent. |
| `review_required`  | Source attribution or internal/provider-return concerns prevent automatic conversion. Inspect `code`.                            |
| `held`             | The batch cannot proceed automatically. Inspect `code` and refund eligibility.                                                   |
| `refund_requested` | A return was requested; it is not complete.                                                                                      |
| `refunded`         | The direct batch refund completed.                                                                                               |

Once `orderId` exists, follow the [ordinary order lifecycle](/products/orchestration/order-lifecycle). Do not restrict `status` to the table above.

`batchState` is `preparing`, `held`, `committed`, `refund_requested`, `refunded`, or null. `committed` means batch initialization completed; it does not mean customer delivery completed. A batch can be `refund_requested` while the order's `status` still says `paused`.

Useful deposit reasons include:

| `code`                                                                                            | Meaning and next action                                                                                                     |
| ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `standing_address_paused`                                                                         | Resume if conversion is desired, or request an eligible refund.                                                             |
| `amount_too_small`, `xchain_amount_too_small`                                                     | Apply the source-specific dust rules.                                                                                       |
| `standing_identity_pair`                                                                          | Source and destination are the same chain/asset. These deposits are held rather than forwarded; request an eligible refund. |
| `standing_internal_funding`, `standing_suspected_provider_return`, `standing_sender_unattributed` | Attribution or custody needs review. Another deposit does not resolve the cause.                                            |

This is not an exhaustive error enum. Retain the server's `code`, show a pending/review state for unfamiliar nonterminal outcomes, and reconcile with the order when one exists.

## Request a refund

`POST /v1/standing-deposit-addresses/{ref}/resolve`

Supply exactly one selector and an explicit source-chain refund target:

```json theme={null}
{
  "depositIds": ["deposit_example"],
  "refundAddress": "<customer-address-on-source-chain>"
}
```

Or:

```json theme={null}
{
  "batchId": "sdb_example",
  "refundAddress": "<customer-address-on-source-chain>"
}
```

| Field           | Rules                                                                                                                                                                                                                                                                 |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `depositIds`    | Array of 1–200 distinct, nonempty IDs. All must belong to this instruction, be confirmed and unreserved, share one source binding and asset, and have `pending`, `below_minimum` or `review_required` materialization status. Bitcoin accepts one output per request. |
| `batchId`       | Nonempty batch ID owned by this instruction. Requestable states are a held batch that has not previously created or funded an order, or a held/committed batch whose existing order is exactly `paused`. Other paused-looking order statuses are not equivalent.      |
| `refundAddress` | Required, nonempty, valid source-chain address. No fallback to the original sender or registration-time target.                                                                                                                                                       |

Do not send both `batchId` and `depositIds`. Unknown fields are rejected. Duplicate deposit IDs fail the ownership/count check; deduplicate before submission.

Response (`202`):

```json theme={null}
{
  "batchId": "sdb_example",
  "status": "refund_requested"
}
```

Acceptance records your authorization. The worker still checks the funds, original senders, target and screening requirements. Screening restrictions cannot be bypassed through this endpoint. Already spent or ambiguous custody cannot be returned from later deposits. A signed refund's target is immutable.

Poll deposits and any associated order until the refund completes or requires review. A direct Bitcoin refund pays the verified recipient output after its transaction fee and requires six confirmations. Do not treat a transaction ID or HTTP `202` alone as final payment.

## HTTP errors

Errors use the [standard envelope](/products/orchestration/api/overview#errors):

```json theme={null}
{
  "error": {
    "code": "instruction_conflict",
    "message": "Customer instructions are immutable"
  }
}
```

| HTTP  | Code                                                 | Action                                                                                                                             |
| ----- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `400` | `validation_error`                                   | Correct field types, ranges, query parameters or unknown fields.                                                                   |
| `400` | `invalid_destination`                                | Choose a destination supported for standing deposits.                                                                              |
| `400` | `invalid_address`                                    | Correct the address for its chain.                                                                                                 |
| `400` | `immutable_instruction`                              | PATCH accepts only `enabled`. Create a new reference for changed instructions.                                                     |
| `400` | `invalid_request`, `unsupported_fee_plan`            | Check affiliate registration, payout configuration and total fee basis points.                                                     |
| `400` | `missing_idempotency_key`, `invalid_idempotency_key` | Supply a key of 1–255 printable ASCII characters.                                                                                  |
| `401` | `unauthorized`                                       | Supply a valid server API key.                                                                                                     |
| `403` | `forbidden`                                          | Client keys cannot use these endpoints.                                                                                            |
| `404` | `not_found`                                          | Check the customer reference, partner account and selected deposit/batch IDs.                                                      |
| `409` | `instruction_conflict`                               | This reference already has a different instruction.                                                                                |
| `409` | `idempotency_conflict`                               | The key was used with a different body. Retry the original request or use a new key for a genuinely new action.                    |
| `409` | `idempotency_in_progress`                            | Wait for `Retry-After` and retry the same request.                                                                                 |
| `409` | `refund_not_available`                               | Refresh state and verify the refund selection and eligibility.                                                                     |
| `503` | `standing_unavailable`, `scanner_unavailable`        | Address issuance or observation is unavailable. Retry with backoff using the same instruction; do not display an inferred address. |

Address screening can also refuse a destination or refund target. Handle the returned error through your normal [risk and compliance flow](/products/orchestration/risk-and-compliance); changing idempotency keys does not bypass it.
