Ondo Perps REST API

REST API for Ondo Perps: account, wallet, deposits/withdrawals, API keys and perpetual-futures trading (orders, TWAP, positions, funding, leverage).

OpenAPI Specification

ondo-finance-perps-openapi-original.json Raw ↑
{
    "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