Ondo Perps REST API
REST API for Ondo Perps: account, wallet, deposits/withdrawals, API keys and perpetual-futures trading (orders, TWAP, positions, funding, leverage).
REST API for Ondo Perps: account, wallet, deposits/withdrawals, API keys and perpetual-futures trading (orders, TWAP, positions, funding, leverage).
{
"openapi": "3.0.3",
"info": {
"title": "Ondo Perps REST API",
"version": "1.0",
"description": "REST API for Ondo Perps: account, wallet, deposits/withdrawals, API keys, and perpetual futures trading."
},
"servers": [{ "url": "https://api.ondoperps.xyz" }],
"security": [{ "BearerAuth": [] }],
"paths": {
"/status": {
"get": {
"summary": "Get Status",
"description": "Returns public API and system status. No authentication required.",
"operationId": "getStatus",
"tags": ["Tool"],
"responses": {
"200": {
"description": "Status response",
"content": {
"application/json": {
"schema": {
"allOf": [
{ "$ref": "#/components/schemas/GenericResponse" },
{
"type": "object",
"properties": {
"result": {
"$ref": "#/components/schemas/StatusResult"
}
}
}
]
},
"example": {
"success": true,
"result": { "marketStatus": "open" }
}
}
}
},
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/hello": {
"get": {
"summary": "Hello",
"description": "Simple health check. Returns a static JSON payload. No authentication required.",
"operationId": "hello",
"tags": ["Tool"],
"responses": {
"200": {
"description": "Hello response",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"hello": { "type": "string", "example": "world" }
}
},
"example": { "hello": "world" }
}
}
},
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/verify_eligibility": {
"get": {
"summary": "Verify Eligibility",
"description": "Used to verify user eligibility (e.g. geography). No authentication required. May be restricted by Cloudflare.",
"operationId": "verifyEligibility",
"tags": ["Tool"],
"responses": {
"200": {
"description": "Eligibility check passed",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": true }
}
},
"example": { "success": true }
}
}
},
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/account": {
"get": {
"summary": "Get Account",
"description": "Returns account information for the authenticated user.",
"operationId": "getAccount",
"tags": ["Account"],
"security": [{ "BearerAuth": [] }, { "ApiKeyAuth": [] }],
"responses": {
"200": {
"description": "Account info",
"content": {
"application/json": {
"schema": {
"allOf": [
{ "$ref": "#/components/schemas/GenericResponse" },
{
"type": "object",
"properties": {
"result": { "$ref": "#/components/schemas/AccountInfo" }
}
}
]
},
"example": {
"success": true,
"result": {
"accountID": "10458932786832481",
"identifier": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
"authType": "web3",
"accountState": "active",
"withdrawalFeeUSD": "0.00",
"termsVersion": 2,
"termsUnixSecs": 1704067200,
"privacyVersion": 1,
"privacyUnixSecs": 1704067200,
"marketingConsent": "accepted"
}
}
}
}
},
"400": {
"description": "Bad request. The request was malformed or failed validation.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": false },
"error": {
"type": "string",
"description": "Human-readable error message"
},
"error_code": {
"type": "string",
"enum": ["account_not_found"]
}
}
},
"example": {
"success": false,
"error": "Description of the error",
"error_code": "account_not_found"
}
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" },
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/account/notifications": {
"get": {
"summary": "Get Notification Preference",
"description": "Returns notification preferences for the authenticated account.",
"operationId": "getAccountNotifications",
"tags": ["Account"],
"security": [{ "BearerAuth": [] }, { "ApiKeyAuth": [] }],
"responses": {
"200": {
"description": "Notification preference",
"content": {
"application/json": {
"schema": {
"allOf": [
{ "$ref": "#/components/schemas/GenericResponse" },
{
"type": "object",
"properties": {
"result": {
"$ref": "#/components/schemas/NotificationPreference"
}
}
}
]
},
"example": {
"success": true,
"result": {
"orderFills": true,
"orderPlaced": false,
"orderCancelled": true
}
}
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" },
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
},
"post": {
"summary": "Set Notification Preference",
"description": "Update notification preferences for the authenticated account.",
"operationId": "setAccountNotifications",
"tags": ["Account"],
"security": [{ "BearerAuth": [] }, { "ApiKeyAuth": [] }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NotificationPreferenceRequest"
}
}
}
},
"responses": {
"200": {
"description": "Updated preference",
"content": {
"application/json": {
"schema": {
"allOf": [
{ "$ref": "#/components/schemas/GenericResponse" },
{
"type": "object",
"properties": {
"result": {
"$ref": "#/components/schemas/NotificationPreference"
}
}
}
]
},
"example": {
"success": true,
"result": {
"orderFills": true,
"orderPlaced": true,
"orderCancelled": false
}
}
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" },
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/auth/erc-4361/login/get_challenge": {
"post": {
"summary": "Get SIWE Login Challenge",
"description": "Get a Sign-In with Ethereum (ERC-4361) challenge for login. No auth required.",
"operationId": "getSIWEChallenge",
"tags": ["Auth"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoginGetChallengeRequest"
}
}
}
},
"responses": {
"200": {
"description": "Challenge message for signing",
"content": {
"application/json": {
"schema": {
"allOf": [
{ "$ref": "#/components/schemas/GenericResponse" },
{
"type": "object",
"properties": {
"result": {
"$ref": "#/components/schemas/AuthChallengeResult"
}
}
}
]
},
"example": {
"success": true,
"result": {
"id": "chg_9f8e7d6c5b4a3210",
"message": "api.ondoperps.xyz wants you to sign in with your Ethereum account:\n0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18\n\nSign in to Ondo Perps\n\nURI: https://api.ondoperps.xyz\nVersion: 1\nChain ID: 1\nNonce: abc123\nIssued At: 2025-03-05T14:30:00Z"
}
}
}
}
},
"400": {
"description": "Bad request. The request was malformed or failed validation.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": false },
"error": {
"type": "string",
"description": "Human-readable error message"
},
"error_code": {
"type": "string",
"enum": ["challenge_not_found"]
}
}
},
"example": {
"success": false,
"error": "Description of the error",
"error_code": "challenge_not_found"
}
}
}
},
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/auth/erc-4361/login/complete_challenge": {
"post": {
"summary": "Complete SIWE Login",
"description": "Complete Sign-In with Ethereum by submitting the signed challenge. Returns JWT.",
"operationId": "completeSIWEChallenge",
"tags": ["Auth"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoginCompleteChallengeRequest"
}
}
}
},
"responses": {
"200": {
"description": "Auth token",
"content": {
"application/json": {
"schema": {
"allOf": [
{ "$ref": "#/components/schemas/GenericResponse" },
{
"type": "object",
"properties": {
"result": { "$ref": "#/components/schemas/AuthToken" }
}
}
]
},
"example": {
"success": true,
"result": {
"identifier": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
"authType": "web3",
"accountId": "10458932786832481",
"issuedAtSecs": 1709648400,
"expirationSecs": 1709734800,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"newAccount": false
}
}
}
}
},
"400": {
"description": "Bad request. The request was malformed or failed validation.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": false },
"error": {
"type": "string",
"description": "Human-readable error message"
},
"error_code": {
"type": "string",
"enum": [
"account_cannot_be_verified",
"challenge_not_found",
"invite_code_already_used",
"invite_code_invalid"
]
}
}
},
"example": {
"success": false,
"error": "Description of the error",
"error_code": "account_cannot_be_verified"
}
}
}
},
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/auth/erc-4361/address_book/get_challenge": {
"post": {
"summary": "Get SIWE Address Book Challenge",
"description": "Get a Sign-In with Ethereum challenge for adding a withdrawal address. Requires auth.",
"operationId": "getSIWEAddressBookChallenge",
"tags": ["Auth"],
"security": [{ "BearerAuth": [] }, { "ApiKeyAuth": [] }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AddressBookGetChallengeRequest"
}
}
}
},
"responses": {
"200": {
"description": "Challenge for signing",
"content": {
"application/json": {
"schema": {
"allOf": [
{ "$ref": "#/components/schemas/GenericResponse" },
{
"type": "object",
"properties": {
"result": {
"$ref": "#/components/schemas/AuthChallengeResult"
}
}
}
]
},
"example": {
"success": true,
"result": {
"id": "chg_ab12cd34ef56",
"message": "Sign this message to add withdrawal address 0x054A94b753CBf65D1Bc484F6D41897b48251fbfF to your address book."
}
}
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" },
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/auth/erc-4361/address_book/complete_challenge": {
"post": {
"summary": "Complete SIWE Address Book Challenge",
"description": "Complete the signed challenge to add a withdrawal address.",
"operationId": "completeSIWEAddressBookChallenge",
"tags": ["Auth"],
"security": [{ "BearerAuth": [] }, { "ApiKeyAuth": [] }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AddressBookCompleteChallengeRequest"
}
}
}
},
"responses": {
"200": {
"description": "Result",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/GenericResponse" },
"example": { "success": true }
}
}
},
"400": {
"description": "Bad request. The request was malformed or failed validation.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": false },
"error": {
"type": "string",
"description": "Human-readable error message"
},
"error_code": {
"type": "string",
"enum": [
"account_not_found",
"bad_label",
"bad_withdrawal_address",
"challenge_not_found",
"empty_label",
"internal_withdrawal_address",
"withdrawal_address_not_found"
]
}
}
},
"example": {
"success": false,
"error": "Description of the error",
"error_code": "account_not_found"
}
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" },
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/auth/invalidate_jwt": {
"get": {
"summary": "Invalidate JWT",
"description": "Invalidates all JWTs for the authenticated account. Requires valid auth.",
"operationId": "invalidateJWT",
"tags": ["Auth"],
"security": [{ "BearerAuth": [] }, { "ApiKeyAuth": [] }],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/GenericResponse" },
"example": { "success": true }
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" },
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/auth/web2/login/google": {
"get": {
"summary": "Login with Google (Web2)",
"description": "Redirects to Google OAuth. No auth required.",
"operationId": "web2LoginGoogle",
"tags": ["Auth"],
"parameters": [
{
"name": "redirect_uri",
"in": "query",
"required": false,
"schema": { "type": "string" }
}
],
"responses": {
"302": { "description": "Redirect to Google" },
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/auth/web2/login/email": {
"get": {
"summary": "Login with Email (Web2)",
"description": "Redirects to email/password login. No auth required.",
"operationId": "web2LoginEmail",
"tags": ["Auth"],
"parameters": [
{
"name": "redirect_uri",
"in": "query",
"required": false,
"schema": { "type": "string" }
}
],
"responses": {
"302": { "description": "Redirect to login" },
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/auth/web2/login/complete": {
"get": {
"summary": "OAuth Login Callback",
"description": "Callback for Web2 OAuth flow. Exchanges code for session. No auth required.",
"operationId": "web2LoginComplete",
"tags": ["Auth"],
"parameters": [
{
"name": "state",
"in": "query",
"required": true,
"schema": { "type": "string" }
},
{
"name": "code",
"in": "query",
"required": false,
"schema": { "type": "string" }
},
{
"name": "error",
"in": "query",
"required": false,
"schema": { "type": "string" }
}
],
"responses": {
"200": { "description": "Redirect or response" },
"400": {
"description": "Bad request. The request was malformed or failed validation.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": false },
"error": {
"type": "string",
"description": "Human-readable error message"
},
"error_code": {
"type": "string",
"enum": [
"auth_invalid",
"email_already_in_use",
"invite_code_already_used",
"invite_code_invalid",
"session_not_found"
]
}
}
},
"example": {
"success": false,
"error": "Description of the error",
"error_code": "auth_invalid"
}
}
}
},
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/auth/web2/get_token": {
"post": {
"summary": "Get Token (Web2)",
"description": "Exchange Web2 session for JWT. Requires valid session cookie.",
"operationId": "web2GetToken",
"tags": ["Auth"],
"responses": {
"200": {
"description": "JWT token",
"content": {
"application/json": {
"schema": {
"allOf": [
{ "$ref": "#/components/schemas/GenericResponse" },
{
"type": "object",
"properties": {
"result": { "$ref": "#/components/schemas/AuthToken" }
}
}
]
},
"example": {
"success": true,
"result": {
"identifier": "user@example.com",
"authType": "web2:google",
"accountId": "10458932786832481",
"issuedAtSecs": 1709648400,
"expirationSecs": 1709734800,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"newAccount": false
}
}
}
}
},
"400": {
"description": "Bad request. The request was malformed or failed validation.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": false },
"error": {
"type": "string",
"description": "Human-readable error message"
},
"error_code": {
"type": "string",
"enum": ["feature_disabled", "session_not_found"]
}
}
},
"example": {
"success": false,
"error": "Description of the error",
"error_code": "feature_disabled"
}
}
}
},
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/auth/web2/address_book": {
"post": {
"summary": "Add Withdrawal Address (Web2)",
"description": "Initiates adding a withdrawal address via Web2 auth. May return MFA challenge.",
"operationId": "web2AddressBook",
"tags": ["Auth"],
"security": [{ "BearerAuth": [] }, { "ApiKeyAuth": [] }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Web2AddressBookRequest"
}
}
}
},
"responses": {
"200": { "description": "Result or MFA challenge" },
"400": {
"description": "Bad request. The request was malformed or failed validation.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": false },
"error": {
"type": "string",
"description": "Human-readable error message"
},
"error_code": {
"type": "string",
"enum": [
"account_not_found",
"auth_invalid",
"bad_label",
"bad_withdrawal_address",
"empty_label",
"invalid_redirect_uri",
"session_not_found",
"withdrawal_address_not_found"
]
}
}
},
"example": {
"success": false,
"error": "Description of the error",
"error_code": "account_not_found"
}
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" },
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/auth/web2/mfa/complete": {
"get": {
"summary": "MFA Callback",
"description": "Callback after MFA completion (e.g. for address book). No auth required.",
"operationId": "web2MfaComplete",
"tags": ["Auth"],
"parameters": [
{
"name": "state",
"in": "query",
"required": true,
"schema": { "type": "string" }
},
{
"name": "code",
"in": "query",
"required": false,
"schema": { "type": "string" }
},
{
"name": "error",
"in": "query",
"required": false,
"schema": { "type": "string" }
}
],
"responses": {
"200": { "description": "Redirect or response" },
"400": {
"description": "Bad request. The request was malformed or failed validation.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": { "type": "boolean", "example": false },
"error": {
"type": "string",
"description": "Human-readable error message"
},
"error_code": {
"type": "string",
"enum": ["auth_invalid", "session_not_found"]
}
}
},
"example": {
"success": false,
"error": "Description of the error",
"error_code": "auth_invalid"
}
}
}
},
"429": { "$ref": "#/components/responses/TooManyRequests" },
"500": { "$ref": "#/components/responses/InternalServerError" }
}
}
},
"/v1/auth/web2/password_reset": {
"post": {
"summary": "Request Password Reset",
"description": "Request a password reset email for Web2 accounts. Requires auth.",
"operationId": "web2PasswordReset",
"tags": ["Auth"],
"security": [{ "BearerAuth": [] }, { "ApiKeyAuth": [] }],
"responses": {
"200": {
"description": "Success",
"content": {
# --- truncated at 32 KB (353 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/ondo-finance/refs/heads/main/openapi/ondo-finance-perps-openapi-original.json