idempotency_key to POST /portfolios/{id}/cash-movements so a retry after a timeout can’t apply a deposit or withdrawal twice.
How it works
Pass a unique string asidempotency_key alongside direction, amount, and comment:
- Same key, same body (
direction,amountandcommentall match): Allocait returns the original result withidempotent_replay: trueand doesn’t apply the movement again. A missingcommentand anullone match. - Same key, different body: the request is refused with
409anderror_code: IDEMPOTENCY_KEY_CONFLICT. - No key: the call is applied normally, with no deduplication. Omit it for a call you know will only ever be made once.
idempotency_key must be 200 characters or fewer), and a key that isn’t a string gets 400.
A call that Allocait refuses, such as a withdrawal that would overdraw cash (INSUFFICIENT_CASH), stores nothing, so a retry with the same key is judged again.
Choose and reuse a key
Generate one key per logical action, such as a UUID or a hash of the action’s inputs, and send the same key on every retry of that action. If two requests with the same key arrive at once, Allocait applies the movement once. No other endpoint in this API accepts an idempotency key. Some writes are safe to repeat because you send the full desired state, not a delta: a repeatedPOST /portfolios/{id}/positions/apply with the same body reaches the same end state. A create is not covered by that. A repeat can add another record or be refused, depending on the route. Cash movements need the key because a deposit or withdrawal is a delta, not a state.
The MCP tool record_cash_movement takes the same idempotency_key, with the same rules. Two kinds of MCP write are safe to repeat without a key. save_position and replace_positions take total shares (negative for a short), so a repeat reaches the same state. A create that reuses a name already taken returns ALREADY_EXISTS with the first record’s id. Check any other write before you repeat it.
Related
- Error codes:
IDEMPOTENCY_KEY_CONFLICT. - Update with an agent: set holdings by state instead of by change.
- Endpoints by task