{
"error": "Unauthorized",
"message": "signature does not match the intent"
}
{
"error": "Forbidden",
"message": "trader is not a permitted partner"
}
{
"error": "Payload Too Large",
"message": "request entity too large"
}
{
"error": "Too Many Requests",
"message": "Rate limit exceeded. Try again in 7s."
}
{
"error": "Internal Server Error",
"message": "Internal Server Error"
}
Orders
Submit an order
One endpoint, three actions. type picks between opening a position, closing one (fully or partially), and withdrawing collateral from one. Pick the variant in the request body below to see the fields each needs.
Reading the response
status is the answer, not the HTTP code. A 200 means the order was submitted and settled; status says how it settled:
status
What happened
filled
It executed. execution carries the tradeId and the resulting amounts.
reverted
It reached the chain and changed nothing. reason says why.
Signing
Every intent is an EIP-712 signature under this domain:
The struct you sign is the intent object itself, and its primaryType is named after the type you send:
type
primaryType
open
OpenIntent
close
CloseIntent
removeCollateral
RemoveCollateralIntent
Declare the fields in the order the request body lists them, and with exactly these solidity widths. EIP-712 hashes the field names AND types into a single typehash, so a different order — or uint256 where the contract says uint192 — is a different type: the digest changes and the contract cannot match your signature. The JSON schema below shows string and integer, which cannot express the widths, so take them from here:
To check your work without spending anything, the wrapper exposes hashOpenIntent, hashCloseIntent and hashRemoveCollateralIntent as view functions — a local digest that matches those is a signature the contract will accept.
Sign as trader: an EOA, or a contract wallet that answers EIP-1271.
One trap the schema cannot warn you about.slippageP is a uint256 on OpenIntent but a uint32 on CloseIntent. The contract types them differently, and signing the wrong width silently changes the digest.
Limits
Checked before anything is submitted, and tighter than the contract itself — an intent the contract would accept can still be refused here:
Field
Allowed
Meaning
slippageP
0 < slippageP ≤ 100
scaled by 10000, so 100 is 1% — the most you can tolerate
closePercentage
0 < closePercentage ≤ 10000
scaled by 10000, so 10000 is 100% and 5000 is half
deadline
now < deadline ≤ now + 60s
unix seconds
Both percentages use the same base of 10000. Neither may be 0: a zero slippageP cannot fill, and the protocol reads a zero closePercentage as a full close.
Before your first order
The trader must be an allowlisted partner, and onboarded once per chain through POST /v1/onboard. Without the delegation an order reaches the chain and reverts as NotDelegate.
Field notes
Send amounts as strings of plain digits — "50000000", not 5e7 or 50000000. They are too large for a JSON number, and rounding one changes the digest.
Addresses can be any casing. Checksummed, lowercase or uppercase all work.
Every field is signed, builder and builderFee included. Nothing can be added or altered between you and the contract.
Rate limit: 30 requests per 10 seconds per IP. Read x-ratelimit-* for the live budget rather than assuming this figure.
Which chain to trade on. Arbitrum One is 42161, Arbitrum Sepolia 421614. Each is served by one host: mainnet by builder.prod.bedrock.ostium.io, testnet by builder.stage.bedrock.ostium.io. Sending a chain to the other host is refused with a 400.
What the order executed as. Present only when status is filled, and the fields depend on the type. Amounts are decimal strings, already scaled.
Show child attributes
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Ostium","colors":{"primary":"#FF5A19","light":"#FF5A19","dark":"#FF5A19"},"logo":"https://mintcdn.com/ostium/rgKhfmKxgkO9O2aD/logo/ostium-logo.svg?fit=max\u0026auto=format\u0026n=rgKhfmKxgkO9O2aD\u0026q=85\u0026s=e2316b63df8fab1bbdb3c18daeff80e5","favicon":"https://mintcdn.com/ostium/PYRmOzvp-N2ht7oL/favicon.svg?fit=max\u0026auto=format\u0026n=PYRmOzvp-N2ht7oL\u0026q=85\u0026s=79bfadbe417502d9aec3c62a2a59d62e","navbar":{"links":[{"href":"https://discord.com/invite/ostiumlabs","label":"Support"}],"primary":{"type":"button","label":"Trade Now","href":"https://app.ostium.com"}},"footer":{"socials":{"x":"https://x.com/Ostium","github":"https://github.com/ostium-labs","linkedin":"https://linkedin.com/company/ostium"},"links":[{"header":"Legal","items":[{"label":"Terms of Use","href":"/legal/terms-of-use"},{"label":"Privacy Policy","href":"/legal/privacy-policy"},{"label":"Nasdaq Subscriber Agreement","href":"/legal/nasdaq-subscriber-agreement"},{"label":"OLP Recovery Plan Terms","href":"/legal/olp-recovery-plan-terms"}]}]},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"styling":{"latex":true},"navigation":{"global":{"anchors":[{"anchor":"Website","icon":"globe","href":"https://ostium.com"},{"anchor":"Developers","icon":"code","href":"/developer/sdk/overview"},{"anchor":"Blog","icon":"newspaper","href":"https://www.ostium.com/blog"},{"anchor":"X/Twitter","icon":"twitter","href":"https://www.x.com/Ostium"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"ostium","hasAudioNarration":false,"actualSubdomain":"ostium","customDomains":["docs.ostium.com"],"gitSource":{"type":"github","owner":"0xostium","repo":"new-docs","deployBranch":"master","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6acc8e98e4af841eed2f1868","collectionId":"2ac89999-3290-4b13-920e-1ca75a2be88f","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6acc8e98e4af841eed2f1868"},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6acc8e98e4af841eed2f1868","clientVersion":"0.0.3966","searchFilterCounts":[{"language":"default","tag":"Developers","count":63},{"language":"default","tag":"Read Methods","count":17},{"language":"default","tag":"API Reference","count":16},{"language":"default","tag":"Traders","count":13},{"language":"default","tag":"Helpers","count":10},{"language":"default","tag":"Client Modes","count":8},{"language":"default","tag":"Builder API","count":7},{"language":"default","tag":"Trading","count":6},{"language":"default","tag":"Write Methods","count":5},{"language":"default","tag":"Previews \u0026 Limits","count":5}]},"assistantConfig":{},"hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/orders/submit-an-order","slug":"/api-reference/orders/submit-an-order","pageMetadata":{"title":"Submit an order","description":"One endpoint, three actions. `type` picks between opening a position, closing one (fully or partially), and withdrawing collateral from one. Pick the variant in the request body below to see the fields each needs.\n\n### Reading the response\n\n**`status` is the answer, not the HTTP code.** A `200` means the order was submitted and settled; `status` says how it settled:\n\n| `status` | What happened |\n| --- | --- |\n| `filled` | It executed. `execution` carries the `tradeId` and the resulting amounts. |\n| `reverted` | It reached the chain and changed nothing. `reason` says why. |\n\n### Signing\n\nEvery intent is an EIP-712 signature under this domain:\n\n```json\n{\n \"name\": \"OstiumAtomicTrading\",\n \"version\": \"1\",\n \"chainId\": 42161,\n \"verifyingContract\": \"0x5eB3960C3fd3274cD81fE5972e0de01084bDa325\"\n}\n```\n\nOn Arbitrum Sepolia (`421614`) it is a different contract, so the domain differs too:\n\n```json\n{\n \"name\": \"OstiumAtomicTrading\",\n \"version\": \"1\",\n \"chainId\": 421614,\n \"verifyingContract\": \"0x32C06a3eC2A40DABf6A8f645f29321cB7236DAA3\"\n}\n```\n\nThe struct you sign is the `intent` object itself, and its `primaryType` is named after the `type` you send:\n\n| `type` | `primaryType` |\n| --- | --- |\n| `open` | `OpenIntent` |\n| `close` | `CloseIntent` |\n| `removeCollateral` | `RemoveCollateralIntent` |\n\nDeclare the fields in the order the request body lists them, **and with exactly these solidity widths**. EIP-712 hashes the field names AND types into a single typehash, so a different order — or `uint256` where the contract says `uint192` — is a different type: the digest changes and the contract cannot match your signature. The JSON schema below shows `string` and `integer`, which cannot express the widths, so take them from here:\n\n```\nOpenIntent(uint256 collateral,uint192 openPrice,uint192 tp,uint192 sl,address trader,\n uint32 leverage,uint16 pairIndex,bool buy,bool isDayTrade,address builder,\n uint32 builderFee,uint256 slippageP,uint256 nonce,uint256 deadline)\n\nCloseIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId,\n uint16 closePercentage,uint192 marketPrice,uint32 slippageP,uint256 nonce,\n uint256 deadline)\n\nRemoveCollateralIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId,\n uint256 removeAmount,uint256 nonce,uint256 deadline)\n```\n\n(Line breaks above are for reading only — the canonical type string has none.)\n\nAs a viem `signTypedData` call:\n\n```ts\nawait account.signTypedData({\n domain, // the OstiumAtomicTrading domain above\n primaryType: 'OpenIntent',\n types: {\n OpenIntent: [\n { name: 'collateral', type: 'uint256' },\n { name: 'openPrice', type: 'uint192' },\n { name: 'tp', type: 'uint192' },\n { name: 'sl', type: 'uint192' },\n { name: 'trader', type: 'address' },\n { name: 'leverage', type: 'uint32' },\n { name: 'pairIndex', type: 'uint16' },\n { name: 'buy', type: 'bool' },\n { name: 'isDayTrade', type: 'bool' },\n { name: 'builder', type: 'address' },\n { name: 'builderFee', type: 'uint32' },\n { name: 'slippageP', type: 'uint256' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n },\n message: intent,\n});\n```\n\nTo check your work without spending anything, the wrapper exposes `hashOpenIntent`, `hashCloseIntent` and `hashRemoveCollateralIntent` as view functions — a local digest that matches those is a signature the contract will accept.\n\nSign as `trader`: an EOA, or a contract wallet that answers EIP-1271.\n\n**One trap the schema cannot warn you about.** `slippageP` is a `uint256` on `OpenIntent` but a `uint32` on `CloseIntent`. The contract types them differently, and signing the wrong width silently changes the digest.\n\n### Limits\n\nChecked before anything is submitted, and tighter than the contract itself — an intent the contract would accept can still be refused here:\n\n| Field | Allowed | Meaning |\n| --- | --- | --- |\n| `slippageP` | `0 \u003c slippageP ≤ 100` | scaled by 10000, so `100` is 1% — the most you can tolerate |\n| `closePercentage` | `0 \u003c closePercentage ≤ 10000` | scaled by 10000, so `10000` is 100% and `5000` is half |\n| `deadline` | `now \u003c deadline ≤ now + 60s` | unix seconds |\n\nBoth percentages use the same base of **10000**. Neither may be `0`: a zero `slippageP` cannot fill, and the protocol reads a zero `closePercentage` as a *full* close.\n\n### Before your first order\n\nThe trader must be an allowlisted partner, and onboarded once per chain through `POST /v1/onboard`. Without the delegation an order reaches the chain and reverts as `NotDelegate`.\n\n### Field notes\n\n- **Send amounts as strings of plain digits** — `\"50000000\"`, not `5e7` or `50000000`. They are too large for a JSON number, and rounding one changes the digest.\n- **Addresses can be any casing.** Checksummed, lowercase or uppercase all work.\n- **Every field is signed**, `builder` and `builderFee` included. Nothing can be added or altered between you and the contract.\n\nRate limit: 30 requests per 10 seconds per IP. Read `x-ratelimit-*` for the live budget rather than assuming this figure.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /v1/orders","href":"/api-reference/orders/submit-an-order","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n em: \"em\",\n h3: \"h3\",\n li: \"li\",\n p: \"p\",\n pre: \"pre\",\n span: \"span\",\n strong: \"strong\",\n table: \"table\",\n tbody: \"tbody\",\n td: \"td\",\n th: \"th\",\n thead: \"thead\",\n tr: \"tr\",\n ul: \"ul\",\n ..._provideComponents(),\n ...props.components\n }, {CodeBlock} = _components;\n if (!CodeBlock) _missingMdxReference(\"CodeBlock\", true);\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"One endpoint, three actions. \", _jsx(_components.code, {\n children: \"type\"\n }), \" picks between opening a position, closing one (fully or partially), and withdrawing collateral from one. Pick the variant in the request body below to see the fields each needs.\"]\n }), \"\\n\", _jsx(_components.h3, {\n children: \"Reading the response\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsxs(_components.strong, {\n children: [_jsx(_components.code, {\n children: \"status\"\n }), \" is the answer, not the HTTP code.\"]\n }), \" A \", _jsx(_components.code, {\n children: \"200\"\n }), \" means the order was submitted and settled; \", _jsx(_components.code, {\n children: \"status\"\n }), \" says how it settled:\"]\n }), \"\\n\", _jsxs(_components.table, {\n children: [_jsx(_components.thead, {\n children: _jsxs(_components.tr, {\n children: [_jsx(_components.th, {\n children: _jsx(_components.code, {\n children: \"status\"\n })\n }), _jsx(_components.th, {\n children: \"What happened\"\n })]\n })\n }), _jsxs(_components.tbody, {\n children: [_jsxs(_components.tr, {\n children: [_jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"filled\"\n })\n }), _jsxs(_components.td, {\n children: [\"It executed. \", _jsx(_components.code, {\n children: \"execution\"\n }), \" carries the \", _jsx(_components.code, {\n children: \"tradeId\"\n }), \" and the resulting amounts.\"]\n })]\n }), _jsxs(_components.tr, {\n children: [_jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"reverted\"\n })\n }), _jsxs(_components.td, {\n children: [\"It reached the chain and changed nothing. \", _jsx(_components.code, {\n children: \"reason\"\n }), \" says why.\"]\n })]\n })]\n })]\n }), \"\\n\", _jsx(_components.h3, {\n children: \"Signing\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"Every intent is an EIP-712 signature under this domain:\"\n }), \"\\n\", _jsx(CodeBlock, {\n numberOfLines: \"6\",\n language: \"json\",\n children: _jsx(_components.pre, {\n className: \"shiki shiki-themes github-light-default dark-plus\",\n style: {\n backgroundColor: \"#ffffff\",\n \"--shiki-dark-bg\": \"#0B0C0E\",\n color: \"#1f2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n language: \"json\",\n children: _jsxs(_components.code, {\n language: \"json\",\n numberOfLines: \"6\",\n children: [_jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"{\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"name\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"OstiumAtomicTrading\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"version\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"1\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"chainId\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0550AE\",\n \"--shiki-dark\": \"#B5CEA8\"\n },\n children: \"42161\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"verifyingContract\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"0x5eB3960C3fd3274cD81fE5972e0de01084bDa325\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"}\"\n })\n }), \"\\n\"]\n })\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"On Arbitrum Sepolia (\", _jsx(_components.code, {\n children: \"421614\"\n }), \") it is a different contract, so the domain differs too:\"]\n }), \"\\n\", _jsx(CodeBlock, {\n numberOfLines: \"6\",\n language: \"json\",\n children: _jsx(_components.pre, {\n className: \"shiki shiki-themes github-light-default dark-plus\",\n style: {\n backgroundColor: \"#ffffff\",\n \"--shiki-dark-bg\": \"#0B0C0E\",\n color: \"#1f2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n language: \"json\",\n children: _jsxs(_components.code, {\n language: \"json\",\n numberOfLines: \"6\",\n children: [_jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"{\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"name\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"OstiumAtomicTrading\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"version\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"1\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"chainId\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0550AE\",\n \"--shiki-dark\": \"#B5CEA8\"\n },\n children: \"421614\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"verifyingContract\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"0x32C06a3eC2A40DABf6A8f645f29321cB7236DAA3\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"}\"\n })\n }), \"\\n\"]\n })\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The struct you sign is the \", _jsx(_components.code, {\n children: \"intent\"\n }), \" object itself, and its \", _jsx(_components.code, {\n children: \"primaryType\"\n }), \" is named after the \", _jsx(_components.code, {\n children: \"type\"\n }), \" you send:\"]\n }), \"\\n\", _jsxs(_components.table, {\n children: [_jsx(_components.thead, {\n children: _jsxs(_components.tr, {\n children: [_jsx(_components.th, {\n children: _jsx(_components.code, {\n children: \"type\"\n })\n }), _jsx(_components.th, {\n children: _jsx(_components.code, {\n children: \"primaryType\"\n })\n })]\n })\n }), _jsxs(_components.tbody, {\n children: [_jsxs(_components.tr, {\n children: [_jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"open\"\n })\n }), _jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"OpenIntent\"\n })\n })]\n }), _jsxs(_components.tr, {\n children: [_jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"close\"\n })\n }), _jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"CloseIntent\"\n })\n })]\n }), _jsxs(_components.tr, {\n children: [_jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"removeCollateral\"\n })\n }), _jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"RemoveCollateralIntent\"\n })\n })]\n })]\n })]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Declare the fields in the order the request body lists them, \", _jsx(_components.strong, {\n children: \"and with exactly these solidity widths\"\n }), \". EIP-712 hashes the field names AND types into a single typehash, so a different order — or \", _jsx(_components.code, {\n children: \"uint256\"\n }), \" where the contract says \", _jsx(_components.code, {\n children: \"uint192\"\n }), \" — is a different type: the digest changes and the contract cannot match your signature. The JSON schema below shows \", _jsx(_components.code, {\n children: \"string\"\n }), \" and \", _jsx(_components.code, {\n children: \"integer\"\n }), \", which cannot express the widths, so take them from here:\"]\n }), \"\\n\", _jsx(CodeBlock, {\n numberOfLines: \"11\",\n language: \"text\",\n children: _jsx(_components.pre, {\n className: \"shiki shiki-themes github-light-default dark-plus\",\n style: {\n backgroundColor: \"#ffffff\",\n \"--shiki-dark-bg\": \"#0B0C0E\",\n color: \"#1f2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n language: \"text\",\n children: _jsxs(_components.code, {\n language: \"text\",\n numberOfLines: \"11\",\n children: [_jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n children: \"OpenIntent(uint256 collateral,uint192 openPrice,uint192 tp,uint192 sl,address trader,\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n children: \" uint32 leverage,uint16 pairIndex,bool buy,bool isDayTrade,address builder,\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n children: \" uint32 builderFee,uint256 slippageP,uint256 nonce,uint256 deadline)\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {})\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n children: \"CloseIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId,\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n children: \" uint16 closePercentage,uint192 marketPrice,uint32 slippageP,uint256 nonce,\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n children: \" uint256 deadline)\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {})\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n children: \"RemoveCollateralIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId,\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n children: \" uint256 removeAmount,uint256 nonce,uint256 deadline)\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {})\n })]\n })\n })\n }), \"\\n\", _jsx(_components.p, {\n children: \"(Line breaks above are for reading only — the canonical type string has none.)\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"As a viem \", _jsx(_components.code, {\n children: \"signTypedData\"\n }), \" call:\"]\n }), \"\\n\", _jsx(CodeBlock, {\n numberOfLines: \"23\",\n language: \"typescript\",\n children: _jsx(_components.pre, {\n className: \"shiki shiki-themes github-light-default dark-plus\",\n style: {\n backgroundColor: \"#ffffff\",\n \"--shiki-dark-bg\": \"#0B0C0E\",\n color: \"#1f2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n language: \"typescript\",\n children: _jsxs(_components.code, {\n language: \"typescript\",\n numberOfLines: \"23\",\n children: [_jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#CF222E\",\n \"--shiki-dark\": \"#C586C0\"\n },\n children: \"await\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" account\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \".\"\n }), _jsx(_components.span, {\n style: {\n color: \"#8250DF\",\n \"--shiki-dark\": \"#DCDCAA\"\n },\n children: \"signTypedData\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"({\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" domain\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#6E7781\",\n \"--shiki-dark\": \"#6A9955\"\n },\n children: \"// the OstiumAtomicTrading domain above\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" primaryType:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'OpenIntent'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" types:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" {\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" OpenIntent:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" [\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'collateral'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'uint256'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'openPrice'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'uint192'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'tp'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'uint192'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'sl'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'uint192'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'trader'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'address'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'leverage'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'uint32'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'pairIndex'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'uint16'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'buy'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'bool'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'isDayTrade'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'bool'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'builder'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'address'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'builderFee'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'uint32'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'slippageP'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'uint256'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'nonce'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'uint256'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" { \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"name:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'deadline'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \", \"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \"type:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \" 'uint256'\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" ],\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" message:\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" intent\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"});\"\n })\n }), \"\\n\"]\n })\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"To check your work without spending anything, the wrapper exposes \", _jsx(_components.code, {\n children: \"hashOpenIntent\"\n }), \", \", _jsx(_components.code, {\n children: \"hashCloseIntent\"\n }), \" and \", _jsx(_components.code, {\n children: \"hashRemoveCollateralIntent\"\n }), \" as view functions — a local digest that matches those is a signature the contract will accept.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Sign as \", _jsx(_components.code, {\n children: \"trader\"\n }), \": an EOA, or a contract wallet that answers EIP-1271.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"One trap the schema cannot warn you about.\"\n }), \" \", _jsx(_components.code, {\n children: \"slippageP\"\n }), \" is a \", _jsx(_components.code, {\n children: \"uint256\"\n }), \" on \", _jsx(_components.code, {\n children: \"OpenIntent\"\n }), \" but a \", _jsx(_components.code, {\n children: \"uint32\"\n }), \" on \", _jsx(_components.code, {\n children: \"CloseIntent\"\n }), \". The contract types them differently, and signing the wrong width silently changes the digest.\"]\n }), \"\\n\", _jsx(_components.h3, {\n children: \"Limits\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"Checked before anything is submitted, and tighter than the contract itself — an intent the contract would accept can still be refused here:\"\n }), \"\\n\", _jsxs(_components.table, {\n children: [_jsx(_components.thead, {\n children: _jsxs(_components.tr, {\n children: [_jsx(_components.th, {\n children: \"Field\"\n }), _jsx(_components.th, {\n children: \"Allowed\"\n }), _jsx(_components.th, {\n children: \"Meaning\"\n })]\n })\n }), _jsxs(_components.tbody, {\n children: [_jsxs(_components.tr, {\n children: [_jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"slippageP\"\n })\n }), _jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"0 \u003c slippageP ≤ 100\"\n })\n }), _jsxs(_components.td, {\n children: [\"scaled by 10000, so \", _jsx(_components.code, {\n children: \"100\"\n }), \" is 1% — the most you can tolerate\"]\n })]\n }), _jsxs(_components.tr, {\n children: [_jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"closePercentage\"\n })\n }), _jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"0 \u003c closePercentage ≤ 10000\"\n })\n }), _jsxs(_components.td, {\n children: [\"scaled by 10000, so \", _jsx(_components.code, {\n children: \"10000\"\n }), \" is 100% and \", _jsx(_components.code, {\n children: \"5000\"\n }), \" is half\"]\n })]\n }), _jsxs(_components.tr, {\n children: [_jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"deadline\"\n })\n }), _jsx(_components.td, {\n children: _jsx(_components.code, {\n children: \"now \u003c deadline ≤ now + 60s\"\n })\n }), _jsx(_components.td, {\n children: \"unix seconds\"\n })]\n })]\n })]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Both percentages use the same base of \", _jsx(_components.strong, {\n children: \"10000\"\n }), \". Neither may be \", _jsx(_components.code, {\n children: \"0\"\n }), \": a zero \", _jsx(_components.code, {\n children: \"slippageP\"\n }), \" cannot fill, and the protocol reads a zero \", _jsx(_components.code, {\n children: \"closePercentage\"\n }), \" as a \", _jsx(_components.em, {\n children: \"full\"\n }), \" close.\"]\n }), \"\\n\", _jsx(_components.h3, {\n children: \"Before your first order\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The trader must be an allowlisted partner, and onboarded once per chain through \", _jsx(_components.code, {\n children: \"POST /v1/onboard\"\n }), \". Without the delegation an order reaches the chain and reverts as \", _jsx(_components.code, {\n children: \"NotDelegate\"\n }), \".\"]\n }), \"\\n\", _jsx(_components.h3, {\n children: \"Field notes\"\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.strong, {\n children: \"Send amounts as strings of plain digits\"\n }), \" — \", _jsx(_components.code, {\n children: \"\\\"50000000\\\"\"\n }), \", not \", _jsx(_components.code, {\n children: \"5e7\"\n }), \" or \", _jsx(_components.code, {\n children: \"50000000\"\n }), \". They are too large for a JSON number, and rounding one changes the digest.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.strong, {\n children: \"Addresses can be any casing.\"\n }), \" Checksummed, lowercase or uppercase all work.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.strong, {\n children: \"Every field is signed\"\n }), \", \", _jsx(_components.code, {\n children: \"builder\"\n }), \" and \", _jsx(_components.code, {\n children: \"builderFee\"\n }), \" included. Nothing can be added or altered between you and the contract.\"]\n }), \"\\n\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Rate limit: 30 requests per 10 seconds per IP. Read \", _jsx(_components.code, {\n children: \"x-ratelimit-*\"\n }), \" for the live budget rather than assuming this figure.\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\nfunction _missingMdxReference(id, component) {\n throw new Error(\"Expected \" + (component ? \"component\" : \"object\") + \" `\" + id + \"` to be defined: you likely forgot to import, pass, or provide it.\");\n}\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Submit an order","description":"One endpoint, three actions. `type` picks between opening a position, closing one (fully or partially), and withdrawing collateral from one. Pick the variant in the request body below to see the fields each needs.\n\n### Reading the response\n\n**`status` is the answer, not the HTTP code.** A `200` means the order was submitted and settled; `status` says how it settled:\n\n| `status` | What happened |\n| --- | --- |\n| `filled` | It executed. `execution` carries the `tradeId` and the resulting amounts. |\n| `reverted` | It reached the chain and changed nothing. `reason` says why. |\n\n### Signing\n\nEvery intent is an EIP-712 signature under this domain:\n\n```json\n{\n \"name\": \"OstiumAtomicTrading\",\n \"version\": \"1\",\n \"chainId\": 42161,\n \"verifyingContract\": \"0x5eB3960C3fd3274cD81fE5972e0de01084bDa325\"\n}\n```\n\nOn Arbitrum Sepolia (`421614`) it is a different contract, so the domain differs too:\n\n```json\n{\n \"name\": \"OstiumAtomicTrading\",\n \"version\": \"1\",\n \"chainId\": 421614,\n \"verifyingContract\": \"0x32C06a3eC2A40DABf6A8f645f29321cB7236DAA3\"\n}\n```\n\nThe struct you sign is the `intent` object itself, and its `primaryType` is named after the `type` you send:\n\n| `type` | `primaryType` |\n| --- | --- |\n| `open` | `OpenIntent` |\n| `close` | `CloseIntent` |\n| `removeCollateral` | `RemoveCollateralIntent` |\n\nDeclare the fields in the order the request body lists them, **and with exactly these solidity widths**. EIP-712 hashes the field names AND types into a single typehash, so a different order — or `uint256` where the contract says `uint192` — is a different type: the digest changes and the contract cannot match your signature. The JSON schema below shows `string` and `integer`, which cannot express the widths, so take them from here:\n\n```\nOpenIntent(uint256 collateral,uint192 openPrice,uint192 tp,uint192 sl,address trader,\n uint32 leverage,uint16 pairIndex,bool buy,bool isDayTrade,address builder,\n uint32 builderFee,uint256 slippageP,uint256 nonce,uint256 deadline)\n\nCloseIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId,\n uint16 closePercentage,uint192 marketPrice,uint32 slippageP,uint256 nonce,\n uint256 deadline)\n\nRemoveCollateralIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId,\n uint256 removeAmount,uint256 nonce,uint256 deadline)\n```\n\n(Line breaks above are for reading only — the canonical type string has none.)\n\nAs a viem `signTypedData` call:\n\n```ts\nawait account.signTypedData({\n domain, // the OstiumAtomicTrading domain above\n primaryType: 'OpenIntent',\n types: {\n OpenIntent: [\n { name: 'collateral', type: 'uint256' },\n { name: 'openPrice', type: 'uint192' },\n { name: 'tp', type: 'uint192' },\n { name: 'sl', type: 'uint192' },\n { name: 'trader', type: 'address' },\n { name: 'leverage', type: 'uint32' },\n { name: 'pairIndex', type: 'uint16' },\n { name: 'buy', type: 'bool' },\n { name: 'isDayTrade', type: 'bool' },\n { name: 'builder', type: 'address' },\n { name: 'builderFee', type: 'uint32' },\n { name: 'slippageP', type: 'uint256' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n },\n message: intent,\n});\n```\n\nTo check your work without spending anything, the wrapper exposes `hashOpenIntent`, `hashCloseIntent` and `hashRemoveCollateralIntent` as view functions — a local digest that matches those is a signature the contract will accept.\n\nSign as `trader`: an EOA, or a contract wallet that answers EIP-1271.\n\n**One trap the schema cannot warn you about.** `slippageP` is a `uint256` on `OpenIntent` but a `uint32` on `CloseIntent`. The contract types them differently, and signing the wrong width silently changes the digest.\n\n### Limits\n\nChecked before anything is submitted, and tighter than the contract itself — an intent the contract would accept can still be refused here:\n\n| Field | Allowed | Meaning |\n| --- | --- | --- |\n| `slippageP` | `0 \u003c slippageP ≤ 100` | scaled by 10000, so `100` is 1% — the most you can tolerate |\n| `closePercentage` | `0 \u003c closePercentage ≤ 10000` | scaled by 10000, so `10000` is 100% and `5000` is half |\n| `deadline` | `now \u003c deadline ≤ now + 60s` | unix seconds |\n\nBoth percentages use the same base of **10000**. Neither may be `0`: a zero `slippageP` cannot fill, and the protocol reads a zero `closePercentage` as a *full* close.\n\n### Before your first order\n\nThe trader must be an allowlisted partner, and onboarded once per chain through `POST /v1/onboard`. Without the delegation an order reaches the chain and reverts as `NotDelegate`.\n\n### Field notes\n\n- **Send amounts as strings of plain digits** — `\"50000000\"`, not `5e7` or `50000000`. They are too large for a JSON number, and rounding one changes the digest.\n- **Addresses can be any casing.** Checksummed, lowercase or uppercase all work.\n- **Every field is signed**, `builder` and `builderFee` included. Nothing can be added or altered between you and the contract.\n\nRate limit: 30 requests per 10 seconds per IP. Read `x-ratelimit-*` for the live budget rather than assuming this figure.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /v1/orders","href":"/api-reference/orders/submit-an-order","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"summary":"Submit an order","description":"One endpoint, three actions. `type` picks between opening a position, closing one (fully or partially), and withdrawing collateral from one. Pick the variant in the request body below to see the fields each needs.\n\n### Reading the response\n\n**`status` is the answer, not the HTTP code.** A `200` means the order was submitted and settled; `status` says how it settled:\n\n| `status` | What happened |\n| --- | --- |\n| `filled` | It executed. `execution` carries the `tradeId` and the resulting amounts. |\n| `reverted` | It reached the chain and changed nothing. `reason` says why. |\n\n### Signing\n\nEvery intent is an EIP-712 signature under this domain:\n\n```json\n{\n \"name\": \"OstiumAtomicTrading\",\n \"version\": \"1\",\n \"chainId\": 42161,\n \"verifyingContract\": \"0x5eB3960C3fd3274cD81fE5972e0de01084bDa325\"\n}\n```\n\nOn Arbitrum Sepolia (`421614`) it is a different contract, so the domain differs too:\n\n```json\n{\n \"name\": \"OstiumAtomicTrading\",\n \"version\": \"1\",\n \"chainId\": 421614,\n \"verifyingContract\": \"0x32C06a3eC2A40DABf6A8f645f29321cB7236DAA3\"\n}\n```\n\nThe struct you sign is the `intent` object itself, and its `primaryType` is named after the `type` you send:\n\n| `type` | `primaryType` |\n| --- | --- |\n| `open` | `OpenIntent` |\n| `close` | `CloseIntent` |\n| `removeCollateral` | `RemoveCollateralIntent` |\n\nDeclare the fields in the order the request body lists them, **and with exactly these solidity widths**. EIP-712 hashes the field names AND types into a single typehash, so a different order — or `uint256` where the contract says `uint192` — is a different type: the digest changes and the contract cannot match your signature. The JSON schema below shows `string` and `integer`, which cannot express the widths, so take them from here:\n\n```\nOpenIntent(uint256 collateral,uint192 openPrice,uint192 tp,uint192 sl,address trader,\n uint32 leverage,uint16 pairIndex,bool buy,bool isDayTrade,address builder,\n uint32 builderFee,uint256 slippageP,uint256 nonce,uint256 deadline)\n\nCloseIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId,\n uint16 closePercentage,uint192 marketPrice,uint32 slippageP,uint256 nonce,\n uint256 deadline)\n\nRemoveCollateralIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId,\n uint256 removeAmount,uint256 nonce,uint256 deadline)\n```\n\n(Line breaks above are for reading only — the canonical type string has none.)\n\nAs a viem `signTypedData` call:\n\n```ts\nawait account.signTypedData({\n domain, // the OstiumAtomicTrading domain above\n primaryType: 'OpenIntent',\n types: {\n OpenIntent: [\n { name: 'collateral', type: 'uint256' },\n { name: 'openPrice', type: 'uint192' },\n { name: 'tp', type: 'uint192' },\n { name: 'sl', type: 'uint192' },\n { name: 'trader', type: 'address' },\n { name: 'leverage', type: 'uint32' },\n { name: 'pairIndex', type: 'uint16' },\n { name: 'buy', type: 'bool' },\n { name: 'isDayTrade', type: 'bool' },\n { name: 'builder', type: 'address' },\n { name: 'builderFee', type: 'uint32' },\n { name: 'slippageP', type: 'uint256' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n },\n message: intent,\n});\n```\n\nTo check your work without spending anything, the wrapper exposes `hashOpenIntent`, `hashCloseIntent` and `hashRemoveCollateralIntent` as view functions — a local digest that matches those is a signature the contract will accept.\n\nSign as `trader`: an EOA, or a contract wallet that answers EIP-1271.\n\n**One trap the schema cannot warn you about.** `slippageP` is a `uint256` on `OpenIntent` but a `uint32` on `CloseIntent`. The contract types them differently, and signing the wrong width silently changes the digest.\n\n### Limits\n\nChecked before anything is submitted, and tighter than the contract itself — an intent the contract would accept can still be refused here:\n\n| Field | Allowed | Meaning |\n| --- | --- | --- |\n| `slippageP` | `0 \u003c slippageP ≤ 100` | scaled by 10000, so `100` is 1% — the most you can tolerate |\n| `closePercentage` | `0 \u003c closePercentage ≤ 10000` | scaled by 10000, so `10000` is 100% and `5000` is half |\n| `deadline` | `now \u003c deadline ≤ now + 60s` | unix seconds |\n\nBoth percentages use the same base of **10000**. Neither may be `0`: a zero `slippageP` cannot fill, and the protocol reads a zero `closePercentage` as a *full* close.\n\n### Before your first order\n\nThe trader must be an allowlisted partner, and onboarded once per chain through `POST /v1/onboard`. Without the delegation an order reaches the chain and reverts as `NotDelegate`.\n\n### Field notes\n\n- **Send amounts as strings of plain digits** — `\"50000000\"`, not `5e7` or `50000000`. They are too large for a JSON number, and rounding one changes the digest.\n- **Addresses can be any casing.** Checksummed, lowercase or uppercase all work.\n- **Every field is signed**, `builder` and `builderFee` included. Nothing can be added or altered between you and the contract.\n\nRate limit: 30 requests per 10 seconds per IP. Read `x-ratelimit-*` for the live budget rather than assuming this figure.","tags":["Orders"],"requestBody":"44caa580-69e9-4adf-8d82-1a94d4c4560b","responses":{"200":"4129dedc-d9cf-4cbd-971d-46ecb02bcaf2","400":"e57c182d-08a6-4003-b570-e004fdaf1ea4","401":"9891cbef-7c4f-4b0b-8302-a84c20877011","403":"1f9ea367-c8f8-422d-abad-888248944a64","413":"06385b89-f9a6-4bd6-b803-fb1a40d187b7","429":"68a94bfb-8d35-4907-a75e-5b6bde74af03","500":"49a76876-01f2-4c31-bba9-ef26161b7f50"},"method":"post","type":"path","servers":["35ccf0da-4e4c-4ce1-a160-3dfb930fa193","14a6e080-29f2-4577-ab29-a205a0e38f12"],"security":[],"path":"/v1/orders","baseUrlOptions":["https://builder.prod.bedrock.ostium.io","https://builder.stage.bedrock.ostium.io"],"title":"Submit an order","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{},"requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Open","required":["type","chainId","intent","signature"],"properties":{"type":{"type":"string","enum":["open"],"isRequired":true,"uniqueKey":"oneOf.0.type","typeLabel":"enum\u003cstring>"},"chainId":{"oneOf":[{"type":"number","description":"Which chain to trade on. Arbitrum One is 42161, Arbitrum Sepolia 421614. Each is served by one host: mainnet by `builder.prod.bedrock.ostium.io`, testnet by `builder.stage.bedrock.ostium.io`. Sending a chain to the other host is refused with a 400.","enum":[42161],"example":42161,"isRequired":true,"uniqueKey":"oneOf.0.chainId.oneOf.0","typeLabel":"enum\u003cnumber>"},{"type":"number","description":"Which chain to trade on. Arbitrum One is 42161, Arbitrum Sepolia 421614. Each is served by one host: mainnet by `builder.prod.bedrock.ostium.io`, testnet by `builder.stage.bedrock.ostium.io`. Sending a chain to the other host is refused with a 400.","enum":[421614],"example":42161,"isRequired":true,"uniqueKey":"oneOf.0.chainId.oneOf.1","typeLabel":"enum\u003cnumber>"}],"isRequired":true,"uniqueKey":"oneOf.0.chainId","typeLabel":"enum\u003cnumber>"},"intent":{"type":"object","properties":{"collateral":{"type":"string","pattern":"^\\d+$","description":"Margin you are putting up in USDC, scaled by 1e6 — 10 USDC is `\"10000000\"`. Example: `\"50000000\"`.","example":"50000000","isRequired":true,"uniqueKey":"oneOf.0.intent.collateral","typeLabel":"string"},"openPrice":{"type":"string","pattern":"^\\d+$","description":"The price you are willing to open at, scaled by 1e18 — 79680.28 is `\"79680280000000000000000\"`. This is a bound, not the fill — the executed price may be better, and worse is rejected by `slippageP`. Use the current ask for a long and the bid for a short; `GET /v1/prices/{pair}` returns both.","example":"79680280000000000000000","isRequired":true,"uniqueKey":"oneOf.0.intent.openPrice","typeLabel":"string"},"tp":{"type":"string","pattern":"^\\d+$","description":"Take-profit price, scaled by 1e18 — 79680.28 is `\"79680280000000000000000\"`. Send `\"0\"` for none.","example":"0","isRequired":true,"uniqueKey":"oneOf.0.intent.tp","typeLabel":"string"},"sl":{"type":"string","pattern":"^\\d+$","description":"Stop-loss price, scaled by 1e18 — 79680.28 is `\"79680280000000000000000\"`. Send `\"0\"` for none.","example":"0","isRequired":true,"uniqueKey":"oneOf.0.intent.sl","typeLabel":"string"},"trader":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$","description":"The address signing this intent, and the one that will hold the trade.","example":"0x98279066957A9eAF627D33983409A548CF3e2207","isRequired":true,"uniqueKey":"oneOf.0.intent.trader","typeLabel":"string"},"leverage":{"type":"integer","description":"Leverage, scaled by 100 — 10x is `1000`. The maximum is per-pair: read `group.maxLeverage` from the pairs list, or see the Markets section.","minimum":1,"example":1000,"isRequired":true,"uniqueKey":"oneOf.0.intent.leverage","typeLabel":"integer"},"pairIndex":{"type":"integer","description":"The pair's id, as returned by `GET /v1/pairs` in `id` — BTC-USD is `0`. It is not a position in that list: do not derive it by counting rows. See the Markets section for the full set.","minimum":0,"example":0,"isRequired":true,"uniqueKey":"oneOf.0.intent.pairIndex","typeLabel":"integer"},"buy":{"type":"boolean","description":"`true` opens a long, `false` a short.","example":true,"isRequired":true,"uniqueKey":"oneOf.0.intent.buy","typeLabel":"boolean"},"isDayTrade":{"type":"boolean","description":"Marks the trade as intraday. Send `false` unless you are opening a day trade.","example":false,"isRequired":true,"uniqueKey":"oneOf.0.intent.isDayTrade","typeLabel":"boolean"},"builder":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$","description":"Address credited for this trade. Send the zero address `0x0000000000000000000000000000000000000000` unless you are attributing flow to a builder.","example":"0x98279066957A9eAF627D33983409A548CF3e2207","isRequired":true,"uniqueKey":"oneOf.0.intent.builder","typeLabel":"string"},"builderFee":{"type":"integer","description":"Fee paid to `builder`, scaled by 10000 — `100` is 1%. Send `0` when `builder` is the zero address.","minimum":0,"example":0,"isRequired":true,"uniqueKey":"oneOf.0.intent.builderFee","typeLabel":"integer"},"slippageP":{"type":"string","pattern":"^\\d+$","description":"How much worse than `openPrice` you will accept, scaled by 10000 — `100` is 1%. Must be `0 \u003c slippageP \u003c= 100`. A fill worse than this reverts instead.","example":"100","isRequired":true,"uniqueKey":"oneOf.0.intent.slippageP","typeLabel":"string"},"nonce":{"type":"string","pattern":"^\\d+$","description":"Any number this trader has not used before — a random uint256 is fine. There is no counter to follow, so pre-signed intents can be sent in any order. Reusing one that already executed reverts as `NonceAlreadyUsed`.","example":"84305382736775539472473887403939913494969546473727073051743279873203688380042","isRequired":true,"uniqueKey":"oneOf.0.intent.nonce","typeLabel":"string"},"deadline":{"type":"string","pattern":"^\\d+$","description":"Unix seconds after which this intent can no longer be used. Must be in the future and at most 60 seconds ahead — `Math.floor(Date.now() / 1000) + 45` is a good default. Keep it short: until it passes, anyone holding the signature can submit it.","example":"1787916350","isRequired":true,"uniqueKey":"oneOf.0.intent.deadline","typeLabel":"string"}},"required":["collateral","openPrice","tp","sl","trader","leverage","pairIndex","buy","isDayTrade","builder","builderFee","slippageP","nonce","deadline"],"isRequired":true,"uniqueKey":"oneOf.0.intent","typeLabel":"object"},"signature":{"type":"string","pattern":"^0x([a-fA-F0-9]{2})+$","description":"EIP-712 signature: 65-byte ECDSA, or opaque bytes for an ERC-1271 contract wallet","isRequired":true,"uniqueKey":"oneOf.0.signature","typeLabel":"string"}},"uniqueKey":"oneOf.0","typeLabel":"Open · object"},{"type":"object","title":"Close","required":["type","chainId","intent","signature"],"properties":{"type":{"type":"string","enum":["close"],"isRequired":true,"uniqueKey":"oneOf.1.type","typeLabel":"enum\u003cstring>"},"chainId":{"oneOf":[{"type":"number","description":"Which chain to trade on. Arbitrum One is 42161, Arbitrum Sepolia 421614. Each is served by one host: mainnet by `builder.prod.bedrock.ostium.io`, testnet by `builder.stage.bedrock.ostium.io`. Sending a chain to the other host is refused with a 400.","enum":[42161],"example":42161,"isRequired":true,"uniqueKey":"oneOf.1.chainId.oneOf.0","typeLabel":"enum\u003cnumber>"},{"type":"number","description":"Which chain to trade on. Arbitrum One is 42161, Arbitrum Sepolia 421614. Each is served by one host: mainnet by `builder.prod.bedrock.ostium.io`, testnet by `builder.stage.bedrock.ostium.io`. Sending a chain to the other host is refused with a 400.","enum":[421614],"example":42161,"isRequired":true,"uniqueKey":"oneOf.1.chainId.oneOf.1","typeLabel":"enum\u003cnumber>"}],"isRequired":true,"uniqueKey":"oneOf.1.chainId","typeLabel":"enum\u003cnumber>"},"intent":{"type":"object","properties":{"trader":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$","description":"The address signing this intent. Must be the trade's owner.","example":"0x98279066957A9eAF627D33983409A548CF3e2207","isRequired":true,"uniqueKey":"oneOf.1.intent.trader","typeLabel":"string"},"pairIndex":{"type":"integer","description":"The pair's id, as returned by `GET /v1/pairs` in `id` — not a position in that list. See the Markets section.","minimum":0,"example":0,"isRequired":true,"uniqueKey":"oneOf.1.intent.pairIndex","typeLabel":"integer"},"index":{"type":"integer","minimum":0,"maximum":255,"description":"The trade's slot on that pair — `execution.tradeIndex` from the open.","example":1,"isRequired":true,"uniqueKey":"oneOf.1.intent.index","typeLabel":"integer"},"tradeId":{"type":"string","pattern":"^[1-9]\\d*$","description":"The trade to close — `execution.tradeId` from the open.","example":"151066","isRequired":true,"uniqueKey":"oneOf.1.intent.tradeId","typeLabel":"string"},"closePercentage":{"type":"integer","minimum":1,"maximum":10000,"description":"How much of the position to close, scaled by 10000 — `10000` is the whole thing and `5000` is half. Must be `0 \u003c closePercentage \u003c= 10000`. Never send `0`: the protocol reads it as a full close, so it is refused here.","example":10000,"isRequired":true,"uniqueKey":"oneOf.1.intent.closePercentage","typeLabel":"integer"},"marketPrice":{"type":"string","pattern":"^\\d+$","description":"The price you are willing to close at, scaled by 1e18 — 79680.28 is `\"79680280000000000000000\"`. Use the bid to close a long and the ask to close a short.","example":"79547890000000000000000","isRequired":true,"uniqueKey":"oneOf.1.intent.marketPrice","typeLabel":"string"},"slippageP":{"type":"integer","minimum":1,"maximum":4294967295,"description":"How much worse than `marketPrice` you will accept, scaled by 10000 — `100` is 1%. Must be `0 \u003c slippageP \u003c= 100`. Note this is a number here and a string on `OpenIntent`; the contract types them differently and signing the wrong width changes the digest.","example":100,"isRequired":true,"uniqueKey":"oneOf.1.intent.slippageP","typeLabel":"integer"},"nonce":{"type":"string","pattern":"^\\d+$","description":"Any number this trader has not used before — a random uint256 is fine. There is no counter to follow, so pre-signed intents can be sent in any order. Reusing one that already executed reverts as `NonceAlreadyUsed`.","example":"84305382736775539472473887403939913494969546473727073051743279873203688380042","isRequired":true,"uniqueKey":"oneOf.1.intent.nonce","typeLabel":"string"},"deadline":{"type":"string","pattern":"^\\d+$","description":"Unix seconds after which this intent can no longer be used. Must be in the future and at most 60 seconds ahead — `Math.floor(Date.now() / 1000) + 45` is a good default. Keep it short: until it passes, anyone holding the signature can submit it.","example":"1787916350","isRequired":true,"uniqueKey":"oneOf.1.intent.deadline","typeLabel":"string"}},"required":["trader","pairIndex","index","tradeId","closePercentage","marketPrice","slippageP","nonce","deadline"],"isRequired":true,"uniqueKey":"oneOf.1.intent","typeLabel":"object"},"signature":{"type":"string","pattern":"^0x([a-fA-F0-9]{2})+$","description":"EIP-712 signature: 65-byte ECDSA, or opaque bytes for an ERC-1271 contract wallet","isRequired":true,"uniqueKey":"oneOf.1.signature","typeLabel":"string"}},"uniqueKey":"oneOf.1","typeLabel":"Close · object"},{"type":"object","title":"Remove collateral","required":["type","chainId","intent","signature"],"properties":{"type":{"type":"string","enum":["removeCollateral"],"isRequired":true,"uniqueKey":"oneOf.2.type","typeLabel":"enum\u003cstring>"},"chainId":{"oneOf":[{"type":"number","description":"Which chain to trade on. Arbitrum One is 42161, Arbitrum Sepolia 421614. Each is served by one host: mainnet by `builder.prod.bedrock.ostium.io`, testnet by `builder.stage.bedrock.ostium.io`. Sending a chain to the other host is refused with a 400.","enum":[42161],"example":42161,"isRequired":true,"uniqueKey":"oneOf.2.chainId.oneOf.0","typeLabel":"enum\u003cnumber>"},{"type":"number","description":"Which chain to trade on. Arbitrum One is 42161, Arbitrum Sepolia 421614. Each is served by one host: mainnet by `builder.prod.bedrock.ostium.io`, testnet by `builder.stage.bedrock.ostium.io`. Sending a chain to the other host is refused with a 400.","enum":[421614],"example":42161,"isRequired":true,"uniqueKey":"oneOf.2.chainId.oneOf.1","typeLabel":"enum\u003cnumber>"}],"isRequired":true,"uniqueKey":"oneOf.2.chainId","typeLabel":"enum\u003cnumber>"},"intent":{"type":"object","properties":{"trader":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$","description":"The address signing this intent. Must be the trade's owner.","example":"0x98279066957A9eAF627D33983409A548CF3e2207","isRequired":true,"uniqueKey":"oneOf.2.intent.trader","typeLabel":"string"},"pairIndex":{"type":"integer","description":"The pair's id, as returned by `GET /v1/pairs` in `id` — not a position in that list. See the Markets section.","minimum":0,"example":0,"isRequired":true,"uniqueKey":"oneOf.2.intent.pairIndex","typeLabel":"integer"},"index":{"type":"integer","minimum":0,"maximum":255,"description":"The trade's slot on that pair — `execution.tradeIndex` from the open.","example":1,"isRequired":true,"uniqueKey":"oneOf.2.intent.index","typeLabel":"integer"},"tradeId":{"type":"string","pattern":"^[1-9]\\d*$","description":"The trade to withdraw from.","example":"151066","isRequired":true,"uniqueKey":"oneOf.2.intent.tradeId","typeLabel":"string"},"removeAmount":{"type":"string","pattern":"^[1-9]\\d*$","description":"Collateral to withdraw in USDC, scaled by 1e6 — 10 USDC is `\"10000000\"`. Example: `\"2000000\"`. Withdrawing raises the position's leverage, so it must stay inside the pair's maximum — the new value comes back as `execution.newLeverage`.","example":"2000000","isRequired":true,"uniqueKey":"oneOf.2.intent.removeAmount","typeLabel":"string"},"nonce":{"type":"string","pattern":"^\\d+$","description":"Any number this trader has not used before — a random uint256 is fine. There is no counter to follow, so pre-signed intents can be sent in any order. Reusing one that already executed reverts as `NonceAlreadyUsed`.","example":"84305382736775539472473887403939913494969546473727073051743279873203688380042","isRequired":true,"uniqueKey":"oneOf.2.intent.nonce","typeLabel":"string"},"deadline":{"type":"string","pattern":"^\\d+$","description":"Unix seconds after which this intent can no longer be used. Must be in the future and at most 60 seconds ahead — `Math.floor(Date.now() / 1000) + 45` is a good default. Keep it short: until it passes, anyone holding the signature can submit it.","example":"1787916350","isRequired":true,"uniqueKey":"oneOf.2.intent.deadline","typeLabel":"string"}},"required":["trader","pairIndex","index","tradeId","removeAmount","nonce","deadline"],"isRequired":true,"uniqueKey":"oneOf.2.intent","typeLabel":"object"},"signature":{"type":"string","pattern":"^0x([a-fA-F0-9]{2})+$","description":"EIP-712 signature: 65-byte ECDSA, or opaque bytes for an ERC-1271 contract wallet","isRequired":true,"uniqueKey":"oneOf.2.signature","typeLabel":"string"}},"uniqueKey":"oneOf.2","typeLabel":"Remove collateral · object"}],"uniqueKey":"","typeLabel":"Open · object | Close · object | Remove collateral · object"},"example":{"type":"open","chainId":421614,"intent":{"collateral":"1000000000","openPrice":"2500000000000000000000","tp":"0","sl":"0","trader":"0x2222222222222222222222222222222222222222","leverage":10000,"pairIndex":1,"buy":true,"isDayTrade":false,"builder":"0x0000000000000000000000000000000000000000","builderFee":0,"slippageP":"50","nonce":"42","deadline":"1800000030"},"signature":"0x3045022100abcdef"},"examples":{"Example":{"title":"Example","value":{"type":"open","chainId":421614,"intent":{"collateral":"1000000000","openPrice":"2500000000000000000000","tp":"0","sl":"0","trader":"0x2222222222222222222222222222222222222222","leverage":10000,"pairIndex":1,"buy":true,"isDayTrade":false,"builder":"0x0000000000000000000000000000000000000000","builderFee":0,"slippageP":"50","nonce":"42","deadline":"1800000030"},"signature":"0x3045022100abcdef"}}},"exampleType":"examples"}},"exampleType":"examples"},"responses":{"4129dedc-d9cf-4cbd-971d-46ecb02bcaf2":{"description":"Terminal outcome of the submission","headers":{"x-request-id":{"schema":{"type":"string"},"description":"Always present, and always generated by the service — a value sent on the request is ignored. Use it to correlate a response with your own logs, and quote it when reporting a problem."},"x-ratelimit-limit":{"schema":{"type":"string"},"description":"Requests allowed per window."},"x-ratelimit-remaining":{"schema":{"type":"string"},"description":"Requests left in the current window."},"x-ratelimit-reset":{"schema":{"type":"string"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["filled","reverted"],"description":"`filled` means the order executed. `reverted` means it reached the chain and changed nothing.","isRequired":true,"uniqueKey":"status","typeLabel":"enum\u003cstring>"},"userOpHash":{"type":"string","description":"Identifies the ERC-4337 user operation we submitted for you. Quote it if you need to ask us about a specific order.","example":"0x8c8b184c3208dd11c0275a0cd5a62d0ef0fb4578d1f9b36569b2d346048af4f7","isRequired":true,"uniqueKey":"userOpHash","typeLabel":"string"},"transactionHash":{"type":"string","description":"The transaction it landed in — look it up on Arbiscan.","example":"0x9cae473bf1c8d54da1d32138e7bbe1d2ca05213c98fe70945b402634aac13279","isRequired":true,"uniqueKey":"transactionHash","typeLabel":"string"},"reason":{"type":"string","description":"Why it reverted, decoded where we recognise the error. Present only when `status` is `reverted`.","example":"NotDelegate(0x98279066…, 0x32C06a3e…) — the trader has not delegated","uniqueKey":"reason","typeLabel":"string"},"execution":{"type":"object","properties":{"tradeId":{"type":"string","description":"The trade this order acted on. On an open it is the new trade's id — keep it, you need it to close.","example":"151066","isRequired":true,"uniqueKey":"execution.tradeId","typeLabel":"string"},"tradeIndex":{"type":"number","description":"open only — the slot the protocol assigned","uniqueKey":"execution.tradeIndex","typeLabel":"number"},"fillPrice":{"type":"string","description":"open and close — the price actually executed, which is not the price you signed: that was the bound, this is the fill.","uniqueKey":"execution.fillPrice","typeLabel":"string"},"collateral":{"type":"string","description":"open only — collateral after fees, so lower than what you signed","uniqueKey":"execution.collateral","typeLabel":"string"},"tradeNotional":{"type":"string","description":"open only — how much of the asset the position holds, e.g. `0.0124` BTC. A quantity, not a USD amount.","uniqueKey":"execution.tradeNotional","typeLabel":"string"},"usdcSentToTrader":{"type":"string","description":"close only — what the trader actually received","uniqueKey":"execution.usdcSentToTrader","typeLabel":"string"},"percentProfit":{"type":"string","description":"close only — signed; negative on a loss","uniqueKey":"execution.percentProfit","typeLabel":"string"},"percentClosed":{"type":"string","description":"close only — `100` for a full close","uniqueKey":"execution.percentClosed","typeLabel":"string"},"removedAmount":{"type":"string","description":"removeCollateral only — the collateral withdrawn, in USDC","uniqueKey":"execution.removedAmount","typeLabel":"string"},"newLeverage":{"type":"string","description":"removeCollateral only — the position's leverage after the withdrawal","uniqueKey":"execution.newLeverage","typeLabel":"string"}},"required":["tradeId"],"description":"What the order executed as. Present only when `status` is `filled`, and the fields depend on the `type`. Amounts are decimal strings, already scaled.","uniqueKey":"execution","typeLabel":"object"}},"required":["status","userOpHash","transactionHash"],"uniqueKey":"","typeLabel":"object"},"example":{"status":"filled","userOpHash":"0xaaaa","transactionHash":"0xbbbb","execution":{"tradeId":"150885","tradeIndex":0,"fillPrice":"79680.281023459830864072","collateral":"98.9","tradeNotional":"0.01241210481811446"}},"examples":{"Example":{"title":"Example","value":{"status":"filled","userOpHash":"0xaaaa","transactionHash":"0xbbbb","execution":{"tradeId":"150885","tradeIndex":0,"fillPrice":"79680.281023459830864072","collateral":"98.9","tradeNotional":"0.01241210481811446"}}}},"exampleType":"examples"}},"exampleType":"examples"},"e57c182d-08a6-4003-b570-e004fdaf1ea4":{"description":"Validation failed","headers":{"x-request-id":{"schema":{"type":"string"},"description":"Always present, and always generated by the service — a value sent on the request is ignored. Use it to correlate a response with your own logs, and quote it when reporting a problem."},"x-ratelimit-limit":{"schema":{"type":"string"},"description":"Requests allowed per window."},"x-ratelimit-remaining":{"schema":{"type":"string"},"description":"Requests left in the current window."},"x-ratelimit-reset":{"schema":{"type":"string"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"HTTP status name, e.g. \"Bad Request\"","example":"Bad Request","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"message":{"type":"string","description":"Human-readable detail","example":"Validation failed","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"issues":{"type":"array","items":{"oneOf":[{}],"uniqueKey":"issues.items.[INDEX]","typeLabel":"any"},"description":"Raw zod issue array — present on validation failures only","uniqueKey":"issues","typeLabel":"any[]"},"details":{"description":"Optional structured detail from the thrower","uniqueKey":"details","typeLabel":"any"}},"required":["error","message"],"uniqueKey":"","typeLabel":"object"},"example":{"error":"Bad Request","message":"Validation failed","issues":[]},"examples":{"Example":{"title":"Example","value":{"error":"Bad Request","message":"Validation failed","issues":[]}}},"exampleType":"examples"}},"exampleType":"examples"},"9891cbef-7c4f-4b0b-8302-a84c20877011":{"description":"The signature does not prove control of the intent's `trader`","headers":{"x-request-id":{"schema":{"type":"string"},"description":"Always present, and always generated by the service — a value sent on the request is ignored. Use it to correlate a response with your own logs, and quote it when reporting a problem."},"x-ratelimit-limit":{"schema":{"type":"string"},"description":"Requests allowed per window."},"x-ratelimit-remaining":{"schema":{"type":"string"},"description":"Requests left in the current window."},"x-ratelimit-reset":{"schema":{"type":"string"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"HTTP status name, e.g. \"Bad Request\"","example":"Bad Request","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"message":{"type":"string","description":"Human-readable detail","example":"Validation failed","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"issues":{"type":"array","items":{"oneOf":[{}],"uniqueKey":"issues.items.[INDEX]","typeLabel":"any"},"description":"Raw zod issue array — present on validation failures only","uniqueKey":"issues","typeLabel":"any[]"},"details":{"description":"Optional structured detail from the thrower","uniqueKey":"details","typeLabel":"any"}},"required":["error","message"],"uniqueKey":"","typeLabel":"object"},"example":{"error":"Unauthorized","message":"signature does not match the intent"},"examples":{"Example":{"title":"Example","value":{"error":"Unauthorized","message":"signature does not match the intent"}}},"exampleType":"examples"}},"exampleType":"examples"},"1f9ea367-c8f8-422d-abad-888248944a64":{"description":"The `trader` is not a permitted partner","headers":{"x-request-id":{"schema":{"type":"string"},"description":"Always present, and always generated by the service — a value sent on the request is ignored. Use it to correlate a response with your own logs, and quote it when reporting a problem."},"x-ratelimit-limit":{"schema":{"type":"string"},"description":"Requests allowed per window."},"x-ratelimit-remaining":{"schema":{"type":"string"},"description":"Requests left in the current window."},"x-ratelimit-reset":{"schema":{"type":"string"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"HTTP status name, e.g. \"Bad Request\"","example":"Bad Request","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"message":{"type":"string","description":"Human-readable detail","example":"Validation failed","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"issues":{"type":"array","items":{"oneOf":[{}],"uniqueKey":"issues.items.[INDEX]","typeLabel":"any"},"description":"Raw zod issue array — present on validation failures only","uniqueKey":"issues","typeLabel":"any[]"},"details":{"description":"Optional structured detail from the thrower","uniqueKey":"details","typeLabel":"any"}},"required":["error","message"],"uniqueKey":"","typeLabel":"object"},"example":{"error":"Forbidden","message":"trader is not a permitted partner"},"examples":{"Example":{"title":"Example","value":{"error":"Forbidden","message":"trader is not a permitted partner"}}},"exampleType":"examples"}},"exampleType":"examples"},"06385b89-f9a6-4bd6-b803-fb1a40d187b7":{"description":"Request body is larger than the parser limit","headers":{"x-request-id":{"schema":{"type":"string"},"description":"Always present, and always generated by the service — a value sent on the request is ignored. Use it to correlate a response with your own logs, and quote it when reporting a problem."},"x-ratelimit-limit":{"schema":{"type":"string"},"description":"Requests allowed per window."},"x-ratelimit-remaining":{"schema":{"type":"string"},"description":"Requests left in the current window."},"x-ratelimit-reset":{"schema":{"type":"string"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"HTTP status name, e.g. \"Bad Request\"","example":"Bad Request","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"message":{"type":"string","description":"Human-readable detail","example":"Validation failed","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"issues":{"type":"array","items":{"oneOf":[{}],"uniqueKey":"issues.items.[INDEX]","typeLabel":"any"},"description":"Raw zod issue array — present on validation failures only","uniqueKey":"issues","typeLabel":"any[]"},"details":{"description":"Optional structured detail from the thrower","uniqueKey":"details","typeLabel":"any"}},"required":["error","message"],"uniqueKey":"","typeLabel":"object"},"example":{"error":"Payload Too Large","message":"request entity too large"},"examples":{"Example":{"title":"Example","value":{"error":"Payload Too Large","message":"request entity too large"}}},"exampleType":"examples"}},"exampleType":"examples"},"68a94bfb-8d35-4907-a75e-5b6bde74af03":{"description":"Rate limit exceeded","headers":{"x-request-id":{"schema":{"type":"string"},"description":"Always present, and always generated by the service — a value sent on the request is ignored. Use it to correlate a response with your own logs, and quote it when reporting a problem."},"x-ratelimit-limit":{"schema":{"type":"string"},"description":"Requests allowed per window."},"x-ratelimit-remaining":{"schema":{"type":"string"},"description":"Requests left in the current window."},"x-ratelimit-reset":{"schema":{"type":"string"},"description":"Seconds until the window resets."},"retry-after":{"schema":{"type":"string"},"description":"Seconds to wait before retrying."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"HTTP status name, e.g. \"Bad Request\"","example":"Bad Request","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"message":{"type":"string","description":"Human-readable detail","example":"Validation failed","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"issues":{"type":"array","items":{"oneOf":[{}],"uniqueKey":"issues.items.[INDEX]","typeLabel":"any"},"description":"Raw zod issue array — present on validation failures only","uniqueKey":"issues","typeLabel":"any[]"},"details":{"description":"Optional structured detail from the thrower","uniqueKey":"details","typeLabel":"any"}},"required":["error","message"],"uniqueKey":"","typeLabel":"object"},"example":{"error":"Too Many Requests","message":"Rate limit exceeded. Try again in 7s."},"examples":{"Example":{"title":"Example","value":{"error":"Too Many Requests","message":"Rate limit exceeded. Try again in 7s."}}},"exampleType":"examples"}},"exampleType":"examples"},"49a76876-01f2-4c31-bba9-ef26161b7f50":{"description":"Unexpected error","headers":{"x-request-id":{"schema":{"type":"string"},"description":"Always present, and always generated by the service — a value sent on the request is ignored. Use it to correlate a response with your own logs, and quote it when reporting a problem."},"x-ratelimit-limit":{"schema":{"type":"string"},"description":"Requests allowed per window."},"x-ratelimit-remaining":{"schema":{"type":"string"},"description":"Requests left in the current window."},"x-ratelimit-reset":{"schema":{"type":"string"},"description":"Seconds until the window resets."}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"HTTP status name, e.g. \"Bad Request\"","example":"Bad Request","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"message":{"type":"string","description":"Human-readable detail","example":"Validation failed","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"issues":{"type":"array","items":{"oneOf":[{}],"uniqueKey":"issues.items.[INDEX]","typeLabel":"any"},"description":"Raw zod issue array — present on validation failures only","uniqueKey":"issues","typeLabel":"any[]"},"details":{"description":"Optional structured detail from the thrower","uniqueKey":"details","typeLabel":"any"}},"required":["error","message"],"uniqueKey":"","typeLabel":"object"},"example":{"error":"Internal Server Error","message":"Internal Server Error"},"examples":{"Example":{"title":"Example","value":{"error":"Internal Server Error","message":"Internal Server Error"}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{},"servers":{"35ccf0da-4e4c-4ce1-a160-3dfb930fa193":{"url":"https://builder.prod.bedrock.ostium.io","description":"Production (Arbitrum One)"},"14a6e080-29f2-4577-ab29-a205a0e38f12":{"url":"https://builder.stage.bedrock.ostium.io","description":"Staging (Arbitrum Sepolia)"}}},"originalFileLocation":"api-reference/openapi.json"},"subdomain":"ostium","siteName":"Ostium","title":"Submit an order - Ostium","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-17T13:14:46.806Z","originalFileLocation":"api-reference/orders/submit-an-order.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"One endpoint, three actions. type picks between opening a position, closing one (fully or partially), and withdrawing collateral from one. Pick the variant in the request body below to see the fields each needs. ### Reading the response status is the answer, not the HTTP code. A 200 means the order was submitted and settled; status says how it settled: | status | What happened | | --- | --- | | filled | It executed. execution carries the tradeId and the resulting amounts. | | reverted | It reached the chain and changed nothing. reason says why. | ### Signing Every intent is an EIP-712 signature under this domain: json { \u0026quot;name\u0026quot;: \u0026quot;OstiumAtomicTrading\u0026quot;, \u0026quot;version\u0026quot;: \u0026quot;1\u0026quot;, \u0026quot;chainId\u0026quot;: 42161, \u0026quot;verifyingContract\u0026quot;: \u0026quot;0x5eB3960C3fd3274cD81fE5972e0de01084bDa325\u0026quot; } On Arbitrum Sepolia (421614) it is a different contract, so the domain differs too: json { \u0026quot;name\u0026quot;: \u0026quot;OstiumAtomicTrading\u0026quot;, \u0026quot;version\u0026quot;: \u0026quot;1\u0026quot;, \u0026quot;chainId\u0026quot;: 421614, \u0026quot;verifyingContract\u0026quot;: \u0026quot;0x32C06a3eC2A40DABf6A8f645f29321cB7236DAA3\u0026quot; } The struct you sign is the intent object itself, and its primaryType is named after the type you send: | type | primaryType | | --- | --- | | open | OpenIntent | | close | CloseIntent | | removeCollateral | RemoveCollateralIntent | Declare the fields in the order the request body lists them, and with exactly these solidity widths. EIP-712 hashes the field names AND types into a single typehash, so a different order — or uint256 where the contract says uint192 — is a different type: the digest changes and the contract cannot match your signature. The JSON schema below shows string and integer, which cannot express the widths, so take them from here: OpenIntent(uint256 collateral,uint192 openPrice,uint192 tp,uint192 sl,address trader, uint32 leverage,uint16 pairIndex,bool buy,bool isDayTrade,address builder, uint32 builderFee,uint256 slippageP,uint256 nonce,uint256 deadline) CloseIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId, uint16 closePercentage,uint192 marketPrice,uint32 slippageP,uint256 nonce, uint256 deadline) RemoveCollateralIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId, uint256 removeAmount,uint256 nonce,uint256 deadline) (Line breaks above are for reading only — the canonical type string has none.) As a viem signTypedData call: ts await account.signTypedData({ domain, // the OstiumAtomicTrading domain above primaryType: \u0026#x27;OpenIntent\u0026#x27;, types: { OpenIntent: [ { name: \u0026#x27;collateral\u0026#x27;, type: \u0026#x27;uint256\u0026#x27; }, { name: \u0026#x27;openPrice\u0026#x27;, type: \u0026#x27;uint192\u0026#x27; }, { name: \u0026#x27;tp\u0026#x27;, type: \u0026#x27;uint192\u0026#x27; }, { name: \u0026#x27;sl\u0026#x27;, type: \u0026#x27;uint192\u0026#x27; }, { name: \u0026#x27;trader\u0026#x27;, type: \u0026#x27;address\u0026#x27; }, { name: \u0026#x27;leverage\u0026#x27;, type: \u0026#x27;uint32\u0026#x27; }, { name: \u0026#x27;pairIndex\u0026#x27;, type: \u0026#x27;uint16\u0026#x27; }, { name: \u0026#x27;buy\u0026#x27;, type: \u0026#x27;bool\u0026#x27; }, { name: \u0026#x27;isDayTrade\u0026#x27;, type: \u0026#x27;bool\u0026#x27; }, { name: \u0026#x27;builder\u0026#x27;, type: \u0026#x27;address\u0026#x27; }, { name: \u0026#x27;builderFee\u0026#x27;, type: \u0026#x27;uint32\u0026#x27; }, { name: \u0026#x27;slippageP\u0026#x27;, type: \u0026#x27;uint256\u0026#x27; }, { name: \u0026#x27;nonce\u0026#x27;, type: \u0026#x27;uint256\u0026#x27; }, { name: \u0026#x27;deadline\u0026#x27;, type: \u0026#x27;uint256\u0026#x27; }, ], }, message: intent, }); To check your work without spending anything, the wrapper exposes hashOpenIntent, hashCloseIntent and hashRemoveCollateralIntent as view functions — a local digest that matches those is a signature the contract will accept. Sign as trader: an EOA, or a contract wallet that answers EIP-1271. One trap the schema cannot warn you about. slippageP is a uint256 on OpenIntent but a uint32 on CloseIntent. The contract types them differently, and signing the wrong width silently changes the digest. ### Limits Checked before anything is submitted, and tighter than the contract itself — an intent the contract would accept can still be refused here: | Field | Allowed | Meaning | | --- | --- | --- | | slippageP | 0 \u0026lt; slippageP ≤ 100 | scaled by 10000, so 100 is 1% — the most you can tolerate | | closePercentage | 0 \u0026lt; closePercentage ≤ 10000 | scaled by 10000, so 10000 is 100% and 5000 is half | | deadline | now \u0026lt; deadline ≤ now + 60s | unix seconds | Both percentages use the same base of 10000. Neither may be 0: a zero slippageP cannot fill, and the protocol reads a zero closePercentage as a full close. ### Before your first order The trader must be an allowlisted partner, and onboarded once per chain through POST /v1/onboard. Without the delegation an order reaches the chain and reverts as NotDelegate. ### Field notes - Send amounts as strings of plain digits — \u0026quot;50000000\u0026quot;, not 5e7 or 50000000. They are too large for a JSON number, and rounding one changes the digest. - Addresses can be any casing. Checksummed, lowercase or uppercase all work. - Every field is signed, builder and builderFee included. Nothing can be added or altered between you and the contract. Rate limit: 30 requests per 10 seconds per IP. Read x-ratelimit-* for the live budget rather than assuming this figure.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Ostium\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/ostium/YrHQiGdYpiT2HO80/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/ostium/YrHQiGdYpiT2HO80/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/ostium/YrHQiGdYpiT2HO80/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/ostium/YrHQiGdYpiT2HO80/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/ostium/YrHQiGdYpiT2HO80/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/ostium/YrHQiGdYpiT2HO80/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/ostium/YrHQiGdYpiT2HO80/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/ostium/YrHQiGdYpiT2HO80/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/ostium/YrHQiGdYpiT2HO80/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Submit an order - Ostium\">\u003cmeta data-mint-head property=\"og:description\" content=\"One endpoint, three actions. type picks between opening a position, closing one (fully or partially), and withdrawing collateral from one. Pick the variant in the request body below to see the fields each needs. ### Reading the response status is the answer, not the HTTP code. A 200 means the order was submitted and settled; status says how it settled: | status | What happened | | --- | --- | | filled | It executed. execution carries the tradeId and the resulting amounts. | | reverted | It reached the chain and changed nothing. reason says why. | ### Signing Every intent is an EIP-712 signature under this domain: json { \u0026quot;name\u0026quot;: \u0026quot;OstiumAtomicTrading\u0026quot;, \u0026quot;version\u0026quot;: \u0026quot;1\u0026quot;, \u0026quot;chainId\u0026quot;: 42161, \u0026quot;verifyingContract\u0026quot;: \u0026quot;0x5eB3960C3fd3274cD81fE5972e0de01084bDa325\u0026quot; } On Arbitrum Sepolia (421614) it is a different contract, so the domain differs too: json { \u0026quot;name\u0026quot;: \u0026quot;OstiumAtomicTrading\u0026quot;, \u0026quot;version\u0026quot;: \u0026quot;1\u0026quot;, \u0026quot;chainId\u0026quot;: 421614, \u0026quot;verifyingContract\u0026quot;: \u0026quot;0x32C06a3eC2A40DABf6A8f645f29321cB7236DAA3\u0026quot; } The struct you sign is the intent object itself, and its primaryType is named after the type you send: | type | primaryType | | --- | --- | | open | OpenIntent | | close | CloseIntent | | removeCollateral | RemoveCollateralIntent | Declare the fields in the order the request body lists them, and with exactly these solidity widths. EIP-712 hashes the field names AND types into a single typehash, so a different order — or uint256 where the contract says uint192 — is a different type: the digest changes and the contract cannot match your signature. The JSON schema below shows string and integer, which cannot express the widths, so take them from here: OpenIntent(uint256 collateral,uint192 openPrice,uint192 tp,uint192 sl,address trader, uint32 leverage,uint16 pairIndex,bool buy,bool isDayTrade,address builder, uint32 builderFee,uint256 slippageP,uint256 nonce,uint256 deadline) CloseIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId, uint16 closePercentage,uint192 marketPrice,uint32 slippageP,uint256 nonce, uint256 deadline) RemoveCollateralIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId, uint256 removeAmount,uint256 nonce,uint256 deadline) (Line breaks above are for reading only — the canonical type string has none.) As a viem signTypedData call: ts await account.signTypedData({ domain, // the OstiumAtomicTrading domain above primaryType: \u0026#x27;OpenIntent\u0026#x27;, types: { OpenIntent: [ { name: \u0026#x27;collateral\u0026#x27;, type: \u0026#x27;uint256\u0026#x27; }, { name: \u0026#x27;openPrice\u0026#x27;, type: \u0026#x27;uint192\u0026#x27; }, { name: \u0026#x27;tp\u0026#x27;, type: \u0026#x27;uint192\u0026#x27; }, { name: \u0026#x27;sl\u0026#x27;, type: \u0026#x27;uint192\u0026#x27; }, { name: \u0026#x27;trader\u0026#x27;, type: \u0026#x27;address\u0026#x27; }, { name: \u0026#x27;leverage\u0026#x27;, type: \u0026#x27;uint32\u0026#x27; }, { name: \u0026#x27;pairIndex\u0026#x27;, type: \u0026#x27;uint16\u0026#x27; }, { name: \u0026#x27;buy\u0026#x27;, type: \u0026#x27;bool\u0026#x27; }, { name: \u0026#x27;isDayTrade\u0026#x27;, type: \u0026#x27;bool\u0026#x27; }, { name: \u0026#x27;builder\u0026#x27;, type: \u0026#x27;address\u0026#x27; }, { name: \u0026#x27;builderFee\u0026#x27;, type: \u0026#x27;uint32\u0026#x27; }, { name: \u0026#x27;slippageP\u0026#x27;, type: \u0026#x27;uint256\u0026#x27; }, { name: \u0026#x27;nonce\u0026#x27;, type: \u0026#x27;uint256\u0026#x27; }, { name: \u0026#x27;deadline\u0026#x27;, type: \u0026#x27;uint256\u0026#x27; }, ], }, message: intent, }); To check your work without spending anything, the wrapper exposes hashOpenIntent, hashCloseIntent and hashRemoveCollateralIntent as view functions — a local digest that matches those is a signature the contract will accept. Sign as trader: an EOA, or a contract wallet that answers EIP-1271. One trap the schema cannot warn you about. slippageP is a uint256 on OpenIntent but a uint32 on CloseIntent. The contract types them differently, and signing the wrong width silently changes the digest. ### Limits Checked before anything is submitted, and tighter than the contract itself — an intent the contract would accept can still be refused here: | Field | Allowed | Meaning | | --- | --- | --- | | slippageP | 0 \u0026lt; slippageP ≤ 100 | scaled by 10000, so 100 is 1% — the most you can tolerate | | closePercentage | 0 \u0026lt; closePercentage ≤ 10000 | scaled by 10000, so 10000 is 100% and 5000 is half | | deadline | now \u0026lt; deadline ≤ now + 60s | unix seconds | Both percentages use the same base of 10000. Neither may be 0: a zero slippageP cannot fill, and the protocol reads a zero closePercentage as a full close. ### Before your first order The trader must be an allowlisted partner, and onboarded once per chain through POST /v1/onboard. Without the delegation an order reaches the chain and reverts as NotDelegate. ### Field notes - Send amounts as strings of plain digits — \u0026quot;50000000\u0026quot;, not 5e7 or 50000000. They are too large for a JSON number, and rounding one changes the digest. - Addresses can be any casing. Checksummed, lowercase or uppercase all work. - Every field is signed, builder and builderFee included. Nothing can be added or altered between you and the contract. Rate limit: 30 requests per 10 seconds per IP. Read x-ratelimit-* for the live budget rather than assuming this figure.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Ostium\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.ostium.com/api-reference/orders/submit-an-order\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://ostium.mintlify.app/_mintlify/api/og/v2?division=Orders\u0026amp;title=Submit+an+order\u0026amp;description=One+endpoint%2C+three+actions.+%60type%60+picks+between+opening+a+position%2C+closing+one+%28fully+or+partially%29%2C+and+withdrawing+collateral+from+one.+Pick+the+variant+in\u0026amp;theme=4c59edf2484b017f3ed2d875\u0026amp;signature=44892434e28b7541abb82f2996f8248a3e57749e2731be00037d85252ac34379\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Submit an order - Ostium\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"One endpoint, three actions. type picks between opening a position, closing one (fully or partially), and withdrawing collateral from one. Pick the variant in the request body below to see the fields each needs. ### Reading the response status is the answer, not the HTTP code. A 200 means the order was submitted and settled; status says how it settled: | status | What happened | | --- | --- | | filled | It executed. execution carries the tradeId and the resulting amounts. | | reverted | It reached the chain and changed nothing. reason says why. | ### Signing Every intent is an EIP-712 signature under this domain: json { \u0026quot;name\u0026quot;: \u0026quot;OstiumAtomicTrading\u0026quot;, \u0026quot;version\u0026quot;: \u0026quot;1\u0026quot;, \u0026quot;chainId\u0026quot;: 42161, \u0026quot;verifyingContract\u0026quot;: \u0026quot;0x5eB3960C3fd3274cD81fE5972e0de01084bDa325\u0026quot; } On Arbitrum Sepolia (421614) it is a different contract, so the domain differs too: json { \u0026quot;name\u0026quot;: \u0026quot;OstiumAtomicTrading\u0026quot;, \u0026quot;version\u0026quot;: \u0026quot;1\u0026quot;, \u0026quot;chainId\u0026quot;: 421614, \u0026quot;verifyingContract\u0026quot;: \u0026quot;0x32C06a3eC2A40DABf6A8f645f29321cB7236DAA3\u0026quot; } The struct you sign is the intent object itself, and its primaryType is named after the type you send: | type | primaryType | | --- | --- | | open | OpenIntent | | close | CloseIntent | | removeCollateral | RemoveCollateralIntent | Declare the fields in the order the request body lists them, and with exactly these solidity widths. EIP-712 hashes the field names AND types into a single typehash, so a different order — or uint256 where the contract says uint192 — is a different type: the digest changes and the contract cannot match your signature. The JSON schema below shows string and integer, which cannot express the widths, so take them from here: OpenIntent(uint256 collateral,uint192 openPrice,uint192 tp,uint192 sl,address trader, uint32 leverage,uint16 pairIndex,bool buy,bool isDayTrade,address builder, uint32 builderFee,uint256 slippageP,uint256 nonce,uint256 deadline) CloseIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId, uint16 closePercentage,uint192 marketPrice,uint32 slippageP,uint256 nonce, uint256 deadline) RemoveCollateralIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId, uint256 removeAmount,uint256 nonce,uint256 deadline) (Line breaks above are for reading only — the canonical type string has none.) As a viem signTypedData call: ts await account.signTypedData({ domain, // the OstiumAtomicTrading domain above primaryType: \u0026#x27;OpenIntent\u0026#x27;, types: { OpenIntent: [ { name: \u0026#x27;collateral\u0026#x27;, type: \u0026#x27;uint256\u0026#x27; }, { name: \u0026#x27;openPrice\u0026#x27;, type: \u0026#x27;uint192\u0026#x27; }, { name: \u0026#x27;tp\u0026#x27;, type: \u0026#x27;uint192\u0026#x27; }, { name: \u0026#x27;sl\u0026#x27;, type: \u0026#x27;uint192\u0026#x27; }, { name: \u0026#x27;trader\u0026#x27;, type: \u0026#x27;address\u0026#x27; }, { name: \u0026#x27;leverage\u0026#x27;, type: \u0026#x27;uint32\u0026#x27; }, { name: \u0026#x27;pairIndex\u0026#x27;, type: \u0026#x27;uint16\u0026#x27; }, { name: \u0026#x27;buy\u0026#x27;, type: \u0026#x27;bool\u0026#x27; }, { name: \u0026#x27;isDayTrade\u0026#x27;, type: \u0026#x27;bool\u0026#x27; }, { name: \u0026#x27;builder\u0026#x27;, type: \u0026#x27;address\u0026#x27; }, { name: \u0026#x27;builderFee\u0026#x27;, type: \u0026#x27;uint32\u0026#x27; }, { name: \u0026#x27;slippageP\u0026#x27;, type: \u0026#x27;uint256\u0026#x27; }, { name: \u0026#x27;nonce\u0026#x27;, type: \u0026#x27;uint256\u0026#x27; }, { name: \u0026#x27;deadline\u0026#x27;, type: \u0026#x27;uint256\u0026#x27; }, ], }, message: intent, }); To check your work without spending anything, the wrapper exposes hashOpenIntent, hashCloseIntent and hashRemoveCollateralIntent as view functions — a local digest that matches those is a signature the contract will accept. Sign as trader: an EOA, or a contract wallet that answers EIP-1271. One trap the schema cannot warn you about. slippageP is a uint256 on OpenIntent but a uint32 on CloseIntent. The contract types them differently, and signing the wrong width silently changes the digest. ### Limits Checked before anything is submitted, and tighter than the contract itself — an intent the contract would accept can still be refused here: | Field | Allowed | Meaning | | --- | --- | --- | | slippageP | 0 \u0026lt; slippageP ≤ 100 | scaled by 10000, so 100 is 1% — the most you can tolerate | | closePercentage | 0 \u0026lt; closePercentage ≤ 10000 | scaled by 10000, so 10000 is 100% and 5000 is half | | deadline | now \u0026lt; deadline ≤ now + 60s | unix seconds | Both percentages use the same base of 10000. Neither may be 0: a zero slippageP cannot fill, and the protocol reads a zero closePercentage as a full close. ### Before your first order The trader must be an allowlisted partner, and onboarded once per chain through POST /v1/onboard. Without the delegation an order reaches the chain and reverts as NotDelegate. ### Field notes - Send amounts as strings of plain digits — \u0026quot;50000000\u0026quot;, not 5e7 or 50000000. They are too large for a JSON number, and rounding one changes the digest. - Addresses can be any casing. Checksummed, lowercase or uppercase all work. - Every field is signed, builder and builderFee included. Nothing can be added or altered between you and the contract. Rate limit: 30 requests per 10 seconds per IP. Read x-ratelimit-* for the live budget rather than assuming this figure.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://ostium.mintlify.app/_mintlify/api/og/v2?division=Orders\u0026amp;title=Submit+an+order\u0026amp;description=One+endpoint%2C+three+actions.+%60type%60+picks+between+opening+a+position%2C+closing+one+%28fully+or+partially%29%2C+and+withdrawing+collateral+from+one.+Pick+the+variant+in\u0026amp;theme=4c59edf2484b017f3ed2d875\u0026amp;signature=44892434e28b7541abb82f2996f8248a3e57749e2731be00037d85252ac34379\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/ostium/YrHQiGdYpiT2HO80/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Ostium\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#FF5A19\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.ostium.com/api-reference/orders/submit-an-order\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/orders/submit-an-order.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.ostium.com/#organization\",\"name\":\"Ostium\",\"url\":\"https://docs.ostium.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/ostium/rgKhfmKxgkO9O2aD/logo/ostium-logo.svg?fit=max\u0026auto=format\u0026n=rgKhfmKxgkO9O2aD\u0026q=85\u0026s=e2316b63df8fab1bbdb3c18daeff80e5\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.ostium.com#website\",\"name\":\"Ostium\",\"url\":\"https://docs.ostium.com\",\"publisher\":{\"@id\":\"https://docs.ostium.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.ostium.com/api-reference/orders/submit-an-order#webpage\",\"url\":\"https://docs.ostium.com/api-reference/orders/submit-an-order\",\"name\":\"Submit an order\",\"description\":\"One endpoint, three actions. type picks between opening a position, closing one (fully or partially), and withdrawing collateral from one. Pick the variant in the request body below to see the fields each needs. ### Reading the response status is the answer, not the HTTP code. A 200 means the order was submitted and settled; status says how it settled: | status | What happened | | --- | --- | | filled | It executed. execution carries the tradeId and the resulting amounts. | | reverted | It reached the chain and changed nothing. reason says why. | ### Signing Every intent is an EIP-712 signature under this domain: json { \\\"name\\\": \\\"OstiumAtomicTrading\\\", \\\"version\\\": \\\"1\\\", \\\"chainId\\\": 42161, \\\"verifyingContract\\\": \\\"0x5eB3960C3fd3274cD81fE5972e0de01084bDa325\\\" } On Arbitrum Sepolia (421614) it is a different contract, so the domain differs too: json { \\\"name\\\": \\\"OstiumAtomicTrading\\\", \\\"version\\\": \\\"1\\\", \\\"chainId\\\": 421614, \\\"verifyingContract\\\": \\\"0x32C06a3eC2A40DABf6A8f645f29321cB7236DAA3\\\" } The struct you sign is the intent object itself, and its primaryType is named after the type you send: | type | primaryType | | --- | --- | | open | OpenIntent | | close | CloseIntent | | removeCollateral | RemoveCollateralIntent | Declare the fields in the order the request body lists them, and with exactly these solidity widths. EIP-712 hashes the field names AND types into a single typehash, so a different order — or uint256 where the contract says uint192 — is a different type: the digest changes and the contract cannot match your signature. The JSON schema below shows string and integer, which cannot express the widths, so take them from here: OpenIntent(uint256 collateral,uint192 openPrice,uint192 tp,uint192 sl,address trader, uint32 leverage,uint16 pairIndex,bool buy,bool isDayTrade,address builder, uint32 builderFee,uint256 slippageP,uint256 nonce,uint256 deadline) CloseIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId, uint16 closePercentage,uint192 marketPrice,uint32 slippageP,uint256 nonce, uint256 deadline) RemoveCollateralIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId, uint256 removeAmount,uint256 nonce,uint256 deadline) (Line breaks above are for reading only — the canonical type string has none.) As a viem signTypedData call: ts await account.signTypedData({ domain, // the OstiumAtomicTrading domain above primaryType: 'OpenIntent', types: { OpenIntent: [ { name: 'collateral', type: 'uint256' }, { name: 'openPrice', type: 'uint192' }, { name: 'tp', type: 'uint192' }, { name: 'sl', type: 'uint192' }, { name: 'trader', type: 'address' }, { name: 'leverage', type: 'uint32' }, { name: 'pairIndex', type: 'uint16' }, { name: 'buy', type: 'bool' }, { name: 'isDayTrade', type: 'bool' }, { name: 'builder', type: 'address' }, { name: 'builderFee', type: 'uint32' }, { name: 'slippageP', type: 'uint256' }, { name: 'nonce', type: 'uint256' }, { name: 'deadline', type: 'uint256' }, ], }, message: intent, }); To check your work without spending anything, the wrapper exposes hashOpenIntent, hashCloseIntent and hashRemoveCollateralIntent as view functions — a local digest that matches those is a signature the contract will accept. Sign as trader: an EOA, or a contract wallet that answers EIP-1271. One trap the schema cannot warn you about. slippageP is a uint256 on OpenIntent but a uint32 on CloseIntent. The contract types them differently, and signing the wrong width silently changes the digest. ### Limits Checked before anything is submitted, and tighter than the contract itself — an intent the contract would accept can still be refused here: | Field | Allowed | Meaning | | --- | --- | --- | | slippageP | 0 \\u003c slippageP ≤ 100 | scaled by 10000, so 100 is 1% — the most you can tolerate | | closePercentage | 0 \\u003c closePercentage ≤ 10000 | scaled by 10000, so 10000 is 100% and 5000 is half | | deadline | now \\u003c deadline ≤ now + 60s | unix seconds | Both percentages use the same base of 10000. Neither may be 0: a zero slippageP cannot fill, and the protocol reads a zero closePercentage as a full close. ### Before your first order The trader must be an allowlisted partner, and onboarded once per chain through POST /v1/onboard. Without the delegation an order reaches the chain and reverts as NotDelegate. ### Field notes - Send amounts as strings of plain digits — \\\"50000000\\\", not 5e7 or 50000000. They are too large for a JSON number, and rounding one changes the digest. - Addresses can be any casing. Checksummed, lowercase or uppercase all work. - Every field is signed, builder and builderFee included. Nothing can be added or altered between you and the contract. Rate limit: 30 requests per 10 seconds per IP. Read x-ratelimit-* for the live budget rather than assuming this figure.\",\"dateModified\":\"2026-09-17T13:14:46.806Z\",\"isPartOf\":{\"@id\":\"https://docs.ostium.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.ostium.com/api-reference/orders/submit-an-order#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.ostium.com/api-reference/orders/submit-an-order#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Orders\",\"item\":\"https://docs.ostium.com/api-reference/orders/one-time-onboarding-gasless\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Submit an order\",\"item\":\"https://docs.ostium.com/api-reference/orders/submit-an-order\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.ostium.com/api-reference/orders/submit-an-order#apireference\",\"headline\":\"Submit an order\",\"name\":\"Submit an order\",\"description\":\"One endpoint, three actions. type picks between opening a position, closing one (fully or partially), and withdrawing collateral from one. Pick the variant in the request body below to see the fields each needs. ### Reading the response status is the answer, not the HTTP code. A 200 means the order was submitted and settled; status says how it settled: | status | What happened | | --- | --- | | filled | It executed. execution carries the tradeId and the resulting amounts. | | reverted | It reached the chain and changed nothing. reason says why. | ### Signing Every intent is an EIP-712 signature under this domain: json { \\\"name\\\": \\\"OstiumAtomicTrading\\\", \\\"version\\\": \\\"1\\\", \\\"chainId\\\": 42161, \\\"verifyingContract\\\": \\\"0x5eB3960C3fd3274cD81fE5972e0de01084bDa325\\\" } On Arbitrum Sepolia (421614) it is a different contract, so the domain differs too: json { \\\"name\\\": \\\"OstiumAtomicTrading\\\", \\\"version\\\": \\\"1\\\", \\\"chainId\\\": 421614, \\\"verifyingContract\\\": \\\"0x32C06a3eC2A40DABf6A8f645f29321cB7236DAA3\\\" } The struct you sign is the intent object itself, and its primaryType is named after the type you send: | type | primaryType | | --- | --- | | open | OpenIntent | | close | CloseIntent | | removeCollateral | RemoveCollateralIntent | Declare the fields in the order the request body lists them, and with exactly these solidity widths. EIP-712 hashes the field names AND types into a single typehash, so a different order — or uint256 where the contract says uint192 — is a different type: the digest changes and the contract cannot match your signature. The JSON schema below shows string and integer, which cannot express the widths, so take them from here: OpenIntent(uint256 collateral,uint192 openPrice,uint192 tp,uint192 sl,address trader, uint32 leverage,uint16 pairIndex,bool buy,bool isDayTrade,address builder, uint32 builderFee,uint256 slippageP,uint256 nonce,uint256 deadline) CloseIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId, uint16 closePercentage,uint192 marketPrice,uint32 slippageP,uint256 nonce, uint256 deadline) RemoveCollateralIntent(address trader,uint16 pairIndex,uint8 index,uint256 tradeId, uint256 removeAmount,uint256 nonce,uint256 deadline) (Line breaks above are for reading only — the canonical type string has none.) As a viem signTypedData call: ts await account.signTypedData({ domain, // the OstiumAtomicTrading domain above primaryType: 'OpenIntent', types: { OpenIntent: [ { name: 'collateral', type: 'uint256' }, { name: 'openPrice', type: 'uint192' }, { name: 'tp', type: 'uint192' }, { name: 'sl', type: 'uint192' }, { name: 'trader', type: 'address' }, { name: 'leverage', type: 'uint32' }, { name: 'pairIndex', type: 'uint16' }, { name: 'buy', type: 'bool' }, { name: 'isDayTrade', type: 'bool' }, { name: 'builder', type: 'address' }, { name: 'builderFee', type: 'uint32' }, { name: 'slippageP', type: 'uint256' }, { name: 'nonce', type: 'uint256' }, { name: 'deadline', type: 'uint256' }, ], }, message: intent, }); To check your work without spending anything, the wrapper exposes hashOpenIntent, hashCloseIntent and hashRemoveCollateralIntent as view functions — a local digest that matches those is a signature the contract will accept. Sign as trader: an EOA, or a contract wallet that answers EIP-1271. One trap the schema cannot warn you about. slippageP is a uint256 on OpenIntent but a uint32 on CloseIntent. The contract types them differently, and signing the wrong width silently changes the digest. ### Limits Checked before anything is submitted, and tighter than the contract itself — an intent the contract would accept can still be refused here: | Field | Allowed | Meaning | | --- | --- | --- | | slippageP | 0 \\u003c slippageP ≤ 100 | scaled by 10000, so 100 is 1% — the most you can tolerate | | closePercentage | 0 \\u003c closePercentage ≤ 10000 | scaled by 10000, so 10000 is 100% and 5000 is half | | deadline | now \\u003c deadline ≤ now + 60s | unix seconds | Both percentages use the same base of 10000. Neither may be 0: a zero slippageP cannot fill, and the protocol reads a zero closePercentage as a full close. ### Before your first order The trader must be an allowlisted partner, and onboarded once per chain through POST /v1/onboard. Without the delegation an order reaches the chain and reverts as NotDelegate. ### Field notes - Send amounts as strings of plain digits — \\\"50000000\\\", not 5e7 or 50000000. They are too large for a JSON number, and rounding one changes the digest. - Addresses can be any casing. Checksummed, lowercase or uppercase all work. - Every field is signed, builder and builderFee included. Nothing can be added or altered between you and the contract. Rate limit: 30 requests per 10 seconds per IP. Read x-ratelimit-* for the live budget rather than assuming this figure.\",\"url\":\"https://docs.ostium.com/api-reference/orders/submit-an-order\",\"mainEntityOfPage\":{\"@id\":\"https://docs.ostium.com/api-reference/orders/submit-an-order#webpage\"},\"dateModified\":\"2026-09-17T13:14:46.806Z\",\"publisher\":{\"@id\":\"https://docs.ostium.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.ostium.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Ostium\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Ostium","nav":{"global":{"anchors":[{"anchor":"Website","icon":"globe","href":"https://ostium.com"},{"anchor":"Developers","icon":"code","href":"/developer/sdk/overview"},{"anchor":"Blog","icon":"newspaper","href":"https://www.ostium.com/blog"},{"anchor":"X/Twitter","icon":"twitter","href":"https://www.x.com/Ostium"}]},"tabs":[{"tab":"Traders","pages":[{"title":"Traders","href":"/traders/welcome"}]},{"tab":"Vault","pages":[{"title":"Vault","href":"/vault/overview"}]},{"tab":"Protocol","pages":[{"title":"Protocol","href":"/protocol/how-ostium-works"}]},{"tab":"Developers","pages":[{"title":"Developers","href":"/developer/sdk/overview"}]},{"tab":"API Reference","groups":[{"group":"Overview","pages":[{"title":"Overview","href":"/api-reference/overview"}]},{"group":"Prices","pages":[{"title":"Latest price for every pair","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/prices","href":"/api-reference/prices/latest-price-for-every-pair"},{"title":"Latest price for one pair","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/prices/{pair}","href":"/api-reference/prices/latest-price-for-one-pair"},{"title":"OHLC candles","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /v1/ohlc","href":"/api-reference/prices/ohlc-candles"},{"title":"Price Stream","href":"/api-reference/price-stream"}]},{"group":"Liquidity","pages":[{"title":"Price for a given trade size","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/depth/{pair}/quote","href":"/api-reference/liquidity/price-for-a-given-trade-size"},{"title":"Price across a range of trade sizes","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/depth/{pair}","href":"/api-reference/liquidity/price-across-a-range-of-trade-sizes"}]},{"group":"Markets","pages":[{"title":"Markets","href":"/api-reference/markets"},{"title":"Every listed pair and its live state","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/pairs","href":"/api-reference/markets/every-listed-pair-and-its-live-state"},{"title":"When each market is open","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/market-hours","href":"/api-reference/markets/when-each-market-is-open"}]},{"group":"Portfolio","pages":[{"title":"Open positions for a wallet","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/trades","href":"/api-reference/portfolio/open-positions-for-a-wallet"},{"title":"Limit/stop orders for a wallet","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/limits","href":"/api-reference/portfolio/limitstop-orders-for-a-wallet"},{"title":"Order history for a wallet","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/orders","href":"/api-reference/portfolio/order-history-for-a-wallet"}]},{"group":"Orders","pages":[{"title":"One-time onboarding (gasless)","description":"A one-time setup step, done gaslessly. Sign two EIP-712 messages offline, post the signatures here, and we relay them on chain and pay for it — the partner never sends a transaction or needs ETH.\n\nRestricted to allowlisted partner addresses. Contact us before integrating.\n\nSend whichever parts you still need; at least one. They are relayed as a single atomic batch, so you are never left with an allowance but no delegate. The response reads both values back from chain, so `state.missing` reflects what is actually set rather than what we submitted.\n\n### The two signatures\n\n**`delegation`** lets the OstiumAtomicTrading wrapper place trades for you.\n\n- Domain: `{ name: \"Ostium\", version: \"1\", chainId, verifyingContract: \u003cTrading> }`\n- Type: `OstiumDelegation(address delegator, address delegate, uint256 nonce, uint256 expiry)`\n- The verifying contract is **Trading**, but `delegate` is the **wrapper** — it is the contract that will call Trading for you, so it is what Trading checks. Sending anything else is rejected.\n\n**`permit`** grants the USDC allowance (ERC-2612).\n\n- Domain: `{ name, version, chainId, verifyingContract: \u003cUSDC> }`\n- Type: `Permit(address owner, address spender, uint256 value, uint256 nonce, uint256 deadline)`\n- `spender` is **TradingStorage**, not Trading — different contracts.\n- Read `name` and `version` from the token itself; they differ between deployments and a wrong domain produces a signature that fails on chain.\n\nBoth nonces come from the chain at signing time — `Trading.delegatableNonces(partner)` and `USDC.nonces(partner)`.\n\n### Addresses\n\n| | Arbitrum (42161) | Arbitrum Sepolia (421614) |\n| --- | --- | --- |\n| Trading | `0x6D0bA1f9996DBD8885827e1b2e8f6593e7702411` | `0x2A9B9c988393f46a2537B0ff11E98c2C15a95afe` |\n| TradingStorage (permit spender) | `0xccd5891083a8acd2074690f65d3024e7d13d66e7` | `0x0b9F5243B29938668c9Cfbd7557A389EC7Ef88b8` |\n| USDC | `0xaf88d065e77c8cc2239327c5edb3a432268e5831` | `0xe73B11Fb1e3eeEe8AF2a23079A4410Fe1B370548` |\n| OstiumAtomicTrading (delegate) | `0x5eB3960C3fd3274cD81fE5972e0de01084bDa325` | `0x32C06a3eC2A40DABf6A8f645f29321cB7236DAA3` |\n\n### Two cases where you send only one half\n\n**On Arbitrum Sepolia there is no permit.** The test token is a plain ERC-20 with no `permit` or `nonces`, so no permit signature exists for it. Send `approve(\u003cTradingStorage>, \u003camount>)` from the wallet, then post `delegation` alone. Mainnet USDC does implement ERC-2612.\n\n**A contract wallet can permit but not delegate.** `setDelegateWithSignature` uses `ecrecover`, which no EIP-1271 signature satisfies. Call `Trading.setDelegate(\u003cOstiumAtomicTrading>)` from the wallet, then post `permit` alone.\n\n### Notes\n\n- **Keep `expiry` and `deadline` short** — 30 minutes is plenty. Until one passes, anyone holding the signature can relay it. They cannot redirect it: `delegate`, `spender` and `value` are all inside the signed bytes.\n- **Numbers are decimal strings**, never JSON numbers. A uint256 nonce or a max allowance exceeds `Number.MAX_SAFE_INTEGER`, and a rounded value no longer matches what you signed.\n\nRate limit: 10 requests per 10 seconds per IP. Read `x-ratelimit-*` for the live budget rather than assuming this figure.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /v1/onboard","href":"/api-reference/orders/one-time-onboarding-gasless"},{"title":"Submit an order","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /v1/orders","href":"/api-reference/orders/submit-an-order"}]},{"group":"Status","pages":[{"title":"Service status","description":"Whether the API can answer usefully right now — not merely whether it is running. `status` is `ok` while the price feed is delivering ticks; `degraded` when none have arrived yet or the feed has gone quiet past its staleness window. Market data endpoints are unreliable while degraded, and quotes should not be trusted.\n\nIt is a feed-wide verdict: one actively trading pair keeps it `ok`, so for a single market still check `timestampSeconds` on that pair's tick.\n\nAlways answers `200`, including when degraded — read `status`, not the HTTP code. Poll it for a health widget or before a batch job; it is not a substitute for checking `timestampSeconds` on the tick you actually trade on.\n\nRate limit: 60 requests per 10 seconds per IP. Read `x-ratelimit-*` for the live budget rather than assuming this figure.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/status","href":"/api-reference/status/service-status"}]}]}]},"title":"Submit an order - Ostium","buildId":"dpl_cadrRc5H9XQiJQbDFN5mcYRs2PAj","deploymentId":"dpl_cadrRc5H9XQiJQbDFN5mcYRs2PAj","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-DKJwRUt2.js","utils-CWD_VS3u.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-oFjciODD.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-C76WsxC3.js","snippetPresets-DvPMxpX_.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","ApiExamples-CuNQfndH.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-BVFpVUoF.js","shallow-t59Jg5Kr.js","getApiPlaygroundDisplay-C_JZ4amX.js","CodeSnippet-CLRDnx_h.js","CodeSnippets-C2myU4kc.js","Page-7TwLLapg.js","getPastedJson-B-JaVXw7.js","icon-BA-iDhH3.js","MethodPill-D4qZABFp.js","DuplicateIcon-THIDKO1O.js","createIcon-CYYJwgFd.js","DynamicMarkdown-UGQuxDKp.js","SectionHeading-jYELb23h.js","axios-vUo_bRtp.js","Markdown-DKsLa3wy.js","clsx-CefdjKz2.js","lib--scc4DXi.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-BaREnp3o.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-sgx_0XzF.js"]}