---
title: "Update an orchestration address"
method: POST
path: "/v2/users/{userId}/orchestration-addresses/{orchestrationAddressId}/update"
tags: ["Orchestration Address"]
---

# Update an orchestration address

`POST /v2/users/{userId}/orchestration-addresses/{orchestrationAddressId}/update`

## Request

- Base URL: `https://production.hifibridge.com`
- URL: `https://production.hifibridge.com/v2/users/{userId}/orchestration-addresses/{orchestrationAddressId}/update`
- Auth: HTTP bearer

Partial update of an existing orchestration address. Any combination of
`mode`, `schedule`, `thresholdAmount`, `offrampMessage`, and `destination.accountId` may
be passed.

**Behavior notes:**
  * Switching mode wipes the irrelevant config columns.
  * Changing `schedule.interval` without an explicit `nextRunAt` resets the next tick to `now + newInterval`.
  * Changing `destination.accountId` re-validates the new account.
  * Queued batches use the current settings when the worker reads the OA to begin creating their offramp. Later edits do not change that attempt or the saved message of an initialized offramp, including on retry.

Cannot update a `DEACTIVATED` address — returns `400 RESOURCE_CONFLICT`.
If the destination, message, mode, or status changes after validation but before
the update is saved, returns `409 RESOURCE_CONFLICT`; reload the settings and retry.

## Path parameters

- `userId` string, required
- `orchestrationAddressId` string, uuid, required

## Request body

- UpdateOrchestrationAddress: Partial update. Any combination of `mode`, `schedule`, `thresholdAmount`, `offrampMessage`, and `destination.accountId` may be set. Same mode cross-rules as create apply to the *resulting* configuration (e.g. switching to `THRESHOLD` requires `thresholdAmount`). **Side effects:** * Switching mode clears schedule-only fields when they no longer apply. * Changing `schedule.interval` without an explicit `nextRunAt` resets the next tick to `now + newInterval`. * Changing `destination.accountId` re-validates the new account (must belong to user, be USD, be an offramp account, etc.). * Queued batches use the current settings when the worker reads the OA to begin offramp initialization. Later edits do not alter that attempt or already-initialized offramps and their saved messages. A `DEACTIVATED` address cannot be updated — returns `400 RESOURCE_CONFLICT`. Concurrent changes to the validated message, destination, mode, or status return `409 RESOURCE_CONFLICT`; reload the current settings and retry the update.
  - `offrampMessage` string, nullable: Optional payment message, preserved exactly. Wire allows at most four lines of 35 characters; ACH allows 10 characters; SWIFT allows 12. Only printable ASCII and newlines are accepted; backslashes and other control characters are rejected. Nonempty messages are unsupported for RTP and other rails. Missing, null, or empty means no message on create; on update omission preserves the setting and null or empty clears it. A destination change revalidates the saved or supplied message. Returns null when unset. Queued batches read current settings when initializing an offramp; initialized offramps retain their saved message on retry.
  - `mode` 'PER_DEPOSIT' | 'SCHEDULED' | 'THRESHOLD': Determines when deposits are converted into an offramp. * `PER_DEPOSIT` — each deposit is batched into its own offramp immediately, UNLESS the cumulative `PENDING` amount is below the destination rail's offramp minimum, in which case the deposit is held `PENDING` and all pending deposits are batched together once their cumulative amount reaches the minimum. * `SCHEDULED` — deposits accumulate until the next schedule boundary (`HOURLY`/`DAILY`/`WEEKLY`), then the entire pending pool is batched together (only if it meets the offramp minimum; otherwise it rolls into the next tick). * `THRESHOLD` — deposits accumulate until their summed amount reaches `thresholdAmount`, then the entire pending pool is batched.
  - `schedule` OrchestrationAddressSchedule: Schedule config for a `SCHEDULED` orchestration address.
    - `interval` 'HOURLY' | 'DAILY' | 'WEEKLY', required: How often a `SCHEDULED` orchestration address rolls up pending deposits into a batch.
    - `nextRunAt` string, date-time: Optional ISO 8601 timestamp for the first scheduled batch. Defaults to `now + interval` if omitted. Subsequent ticks advance by exactly one interval; missed windows (worker downtime) collapse into a single catch-up batch rather than firing N back-to-back.
  - `thresholdAmount` string, nullable: New aggregate threshold. Required if the resulting mode is `THRESHOLD`, and must be at least the destination rail's offramp minimum (else `400`).
  - `destination` object: Partial destination update — only `accountId` may be changed.
    - `accountId` string, uuid, required: New offramp account ID. Same validation as on create.

## Response `200`

A single orchestration address record.

- OrchestrationAddressObject: An orchestration address record.
  - `id` string, uuid: Unique orchestration address ID.
  - `userId` string, uuid: ID of the user that owns this orchestration address.
  - `address` string, nullable: The on-chain wallet address that accepts deposits. `null` while `status=PENDING_WALLET` (provisioning in flight); populated once the wallet exists.
  - `source` object: Source token + chain the address accepts.
    - `currency` 'usdc' | 'usdt'
    - `chain` string: Abbreviated chain name (e.g. `BASE`, `ETHEREUM`, `SOLANA`) — the same form accepted on create and used across the v2 API.
  - `destination` object: Destination payout configuration.
    - `currency` 'usd'
    - `accountId` string, uuid
  - `offrampMessage` string, nullable: Optional payment message, preserved exactly. Wire allows at most four lines of 35 characters; ACH allows 10 characters; SWIFT allows 12. Only printable ASCII and newlines are accepted; backslashes and other control characters are rejected. Nonempty messages are unsupported for RTP and other rails. Missing, null, or empty means no message on create; on update omission preserves the setting and null or empty clears it. A destination change revalidates the saved or supplied message. Returns null when unset. Queued batches read current settings when initializing an offramp; initialized offramps retain their saved message on retry.
  - `mode` 'PER_DEPOSIT' | 'SCHEDULED' | 'THRESHOLD': Determines when deposits are converted into an offramp. * `PER_DEPOSIT` — each deposit is batched into its own offramp immediately, UNLESS the cumulative `PENDING` amount is below the destination rail's offramp minimum, in which case the deposit is held `PENDING` and all pending deposits are batched together once their cumulative amount reaches the minimum. * `SCHEDULED` — deposits accumulate until the next schedule boundary (`HOURLY`/`DAILY`/`WEEKLY`), then the entire pending pool is batched together (only if it meets the offramp minimum; otherwise it rolls into the next tick). * `THRESHOLD` — deposits accumulate until their summed amount reaches `thresholdAmount`, then the entire pending pool is batched.
  - `schedule` object, nullable: Populated only when `mode=SCHEDULED`; `null` otherwise.
    - `interval` 'HOURLY' | 'DAILY' | 'WEEKLY': How often a `SCHEDULED` orchestration address rolls up pending deposits into a batch.
    - `nextRunAt` string, date-time: ISO 8601 timestamp of the next scheduled batch.
  - `thresholdAmount` string, nullable: Populated only when `mode=THRESHOLD`; `null` otherwise. Decimal amount in the source `currency`.
  - `status` 'PENDING_WALLET' | 'ACTIVE' | 'DEACTIVATED': Lifecycle status of the orchestration address. * `PENDING_WALLET` — created but the escrow wallet is still being provisioned. The on-chain `address` is null. Typically transient (a few seconds). * `ACTIVE` — wallet provisioned, ready to receive deposits. * `DEACTIVATED` — soft-deleted. The on-chain wallet still exists and can receive funds, but incoming deposits are recorded with `status=IGNORED` and never offramped.
  - `createdAt` string, date-time
  - `updatedAt` string, date-time
  - `deactivatedAt` string, date-time, nullable: ISO 8601 timestamp when the address was deactivated. `null` if still active.
  - `balance` object, nullable: The escrow wallet's live on-chain balance of the source token. Present ONLY on the single-address GET (`GET /orchestration-addresses/{id}`); the list endpoint omits it to avoid a provider call per row. `null` if the wallet isn't provisioned yet or the balance lookup failed — the GET still returns `200`.
    - `currency` 'usdc' | 'usdt'
    - `amount` string: Decimal balance in the source `currency` (e.g. `"100.500000"`).

## Other responses

- `400`: Bad request - validation error
- `401`: Unauthorized
- `404`: Resource not found
- `409`: Conflict — the request collides with the current state of the resource (e.g. idempotency-key reuse with a different payload).
- `500`: Internal Server Error

## Changes

- **2026-11-03** `319fa6bd5bc6`: 3 info
  - added the new optional request property `offrampMessage`
  - added the non-success response with the status `409`
  - added the optional property `offrampMessage` to the response with the `200` status

[Operation history](https://skmtc.dev/hifi/apis/hifi-api/changes/v2/users/:userId/orchestration-addresses/:orchestrationAddressId/update/post.md)

---

[API](https://skmtc.dev/hifi/apis/hifi-api.md) - [All operations](https://skmtc.dev/hifi/apis/hifi-api/llms.txt) - [OpenAPI document](https://skmtc.dev/hifi/apis/hifi-api/revisions/319fa6bd5bc6?raw)
