Skip to main content

API Reference

warning

The Silhouette API is currently in beta and under active development on testnet. More operations and features will be added soon.

This section provides detailed documentation for each available API operation. All operations use the same endpoint with different operation values in the request body.

login

Authenticate with the Silhouette API using Sign-In With Ethereum (SIWE) to obtain a bearer token. This operation does not require an existing bearer token—it's the first step in using the API.

Endpoint: POST https://api.silhouette.exchange/v0

Authentication: Not required

Request parameters:

ParameterTypeRequiredDescription
operationstringYesMust be "login"
messagestringYesThe SIWE message to verify. Must include the statement "Sign in with Ethereum to the app."
signaturestringYesThe cryptographic signature of the SIWE message, signed with your wallet's private key

Example request:

curl https://api.silhouette.exchange/v0 \
-H "Content-Type: application/json" \
-d '{
"operation": "login",
"message": "api.silhouette.exchange wants you to sign in with your Ethereum account:\n0x1234567890123456789012345678901234567890\n\nSign in with Ethereum to the app.\n\nURI: https://api.silhouette.exchange/login\nVersion: 1\nChain ID: 1\nNonce: abcdefghijklmnopqrstuvwxyz123456\nIssued At: 2024-01-15T10:30:00.000Z",
"signature": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab"
}'

Success response:

{
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZGRyZXNzIjoiMHgxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwIiwiY2hhaW5JZCI6MSwiaWF0IjoxNzA1MzEzNDAwLCJleHAiOjE3MDUzMTcwMDB9.signature_here"
},
"responseMetadata": {
"timestamp": 1705313400,
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}

Error responses:

{
"operation": "login",
"error": "Message and signature are required",
"code": "INVALID_INPUT",
"responseMetadata": {
"timestamp": 1705313400
}
}
{
"operation": "login",
"error": "Invalid signature",
"code": "INVALID_SIGNATURE",
"responseMetadata": {
"timestamp": 1705313400
}
}
{
"operation": "login",
"error": "Invalid statement",
"code": "INVALID_STATEMENT",
"responseMetadata": {
"timestamp": 1705313400
}
}

Notes:

  • The SIWE message must include the exact statement "Sign in with Ethereum to the app." (case-sensitive)
  • The signature must be generated by signing the SIWE message with the private key corresponding to the address in the message
  • The returned JWT token expires after 1 hour by default
  • Store the token securely—you'll need to include it in the Authorization header for all subsequent API requests
  • If your token expires, simply call this operation again to obtain a new token
  • You can use the login assistant for a simplified authentication flow

Related operations: This operation is prerequisite for all other operations except login itself.

getBalances

Retrieve your account balance information for all tokens. This shows your available balance (funds you can trade or withdraw), locked balance (funds tied up in open orders), and total balance.

Endpoint: POST https://api.silhouette.exchange/v0

Authentication: Required

Request parameters:

ParameterTypeRequiredDescription
operationstringYesMust be "getBalances"

Example request:

curl https://api.silhouette.exchange/v0 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{
"operation": "getBalances"
}'

Success response:

{
"data": {
"balances": [
{
"token": "USDC",
"available": "1000000000",
"availableFloat": "1000.0",
"locked": "250000000",
"lockedFloat": "250.0",
"total": "1250000000",
"totalFloat": "1250.0"
}
]
},
"responseMetadata": {
"timestamp": 1705313400,
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}

Response fields:

FieldTypeDescription
tokenstringThe token symbol (e.g., "USDC")
availablestringAvailable balance in the token's smallest unit (can be used for trading or withdrawal)
availableFloatstringAvailable balance as a human-readable decimal number
lockedstringBalance locked in open orders, in the token's smallest unit
lockedFloatstringLocked balance as a human-readable decimal number
totalstringTotal balance (available + locked), in the token's smallest unit
totalFloatstringTotal balance as a human-readable decimal number

Error responses:

{
"operation": "getBalances",
"error": "User 0x1234567890123456789012345678901234567890 not found",
"code": "USER_NOT_FOUND",
"responseMetadata": {
"timestamp": 1705313400
}
}
{
"operation": "getBalances",
"error": "Failed to retrieve balances",
"code": "INTERNAL_ERROR",
"responseMetadata": {
"timestamp": 1705313400
}
}

Notes:

  • Balance values are represented in two formats: raw strings in the token's smallest unit (e.g., micro-USDC for USDC) and human-readable float strings
  • For USDC, the smallest unit is micro-USDC, so "1000000000" represents 1,000 USDC
  • The locked field shows funds currently reserved in open orders and unavailable for new trades or withdrawals
  • The available field shows funds you can immediately use for trading or withdrawal
  • If you have no balance for a token, it won't appear in the response array
  • This operation requires authentication—include your bearer token in the Authorization header

Related operations: Use createOrder to trade with your available balance, or initiateWithdrawal to withdraw available funds.

createOrder

Create a new order to buy or sell tokens. Orders can be either limit orders (executed at a specific price or better) or market orders (executed immediately at the best available price).

Endpoint: POST https://api.silhouette.exchange/v0

Authentication: Required

Request parameters:

ParameterTypeRequiredDescription
operationstringYesMust be "createOrder"
sidestringYesOrder side: "buy" or "sell"
orderTypestringYesOrder type: "limit" or "market"
baseTokenstringYesThe token being traded: "USDC" or "HYPE"
quoteTokenstringYesThe token used for pricing: "USDC" or "HYPE"
amountstringYesOrder amount as a string (can be decimal like "100.5" or scaled integer like "100500000")
pricestringConditionalOrder price (required for limit orders, ignored for market orders). Can be decimal like "1.25" or scaled integer with 6 decimals

Example request (limit order):

curl https://api.silhouette.exchange/v0 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{
"operation": "createOrder",
"side": "buy",
"orderType": "limit",
"baseToken": "HYPE",
"quoteToken": "USDC",
"amount": "100.0",
"price": "1.25"
}'

Example request (market order):

curl https://api.silhouette.exchange/v0 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{
"operation": "createOrder",
"side": "sell",
"orderType": "market",
"baseToken": "HYPE",
"quoteToken": "USDC",
"amount": "50.0"
}'

Success response:

{
"data": {
"message": "Order created successfully.",
"orderId": "550e8400-e29b-41d4-a716-446655440000"
},
"responseMetadata": {
"timestamp": 1705313400,
"requestId": "650e8400-e29b-41d4-a716-446655440001"
}
}

Error responses:

{
"operation": "createOrder",
"error": "Missing required fields: side, orderType, baseToken, quoteToken, and amount are required.",
"code": "VALIDATION_ERROR",
"responseMetadata": {
"timestamp": 1705313400
}
}
{
"operation": "createOrder",
"error": "Invalid orderType. Must be 'limit' or 'market'.",
"code": "VALIDATION_ERROR",
"responseMetadata": {
"timestamp": 1705313400
}
}
{
"operation": "createOrder",
"error": "Failed to create order.",
"code": "ORDER_ERROR",
"responseMetadata": {
"timestamp": 1705313400
}
}

Notes:

  • Order types:
    • "limit": Order executes at the specified price or better. Requires the price parameter.
    • "market": Order executes immediately at the best available price. The price parameter is ignored.
  • Side:
    • "buy": Purchase the base token using the quote token
    • "sell": Sell the base token for the quote token
  • Tokens: Currently supports "USDC" and "HYPE" only
  • Amount format: Can be provided as a decimal string (e.g., "100.5") or as a scaled integer string. Decimal values are automatically converted to the token's smallest unit.
  • Price format: For limit orders, can be decimal (e.g., "1.25") or scaled integer with 6 decimal places. Ignored for market orders.
  • Insufficient balance: The order will fail if you don't have sufficient available balance of the required token
  • Save the returned orderId to cancel or track the order later

Related operations: Use getUserOrders to view your orders, cancelOrder to cancel an open order, and getBalances to check available funds.

cancelOrder

Cancel an existing open order. Once cancelled, any locked funds from the order are returned to your available balance.

Endpoint: POST https://api.silhouette.exchange/v0

Authentication: Required

Request parameters:

ParameterTypeRequiredDescription
operationstringYesMust be "cancelOrder"
orderIdstringYesThe unique identifier of the order to cancel

Example request:

curl https://api.silhouette.exchange/v0 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{
"operation": "cancelOrder",
"orderId": "550e8400-e29b-41d4-a716-446655440000"
}'

Success response:

{
"data": {
"message": "Order cancelled successfully.",
"orderId": "550e8400-e29b-41d4-a716-446655440000"
},
"responseMetadata": {
"timestamp": 1705313400,
"requestId": "650e8400-e29b-41d4-a716-446655440001"
}
}

Error responses:

{
"operation": "cancelOrder",
"error": "Missing required field: orderId.",
"code": "VALIDATION_ERROR",
"responseMetadata": {
"timestamp": 1705313400
}
}
{
"operation": "cancelOrder",
"error": "Failed to cancel order.",
"code": "CANCELLATION_ERROR",
"responseMetadata": {
"timestamp": 1705313400
}
}

Notes:

  • You can only cancel your own orders
  • Orders that have already been filled, partially filled, or cancelled cannot be cancelled
  • When an order is successfully cancelled, any funds that were locked for that order become available in your balance
  • The orderId is returned when you create an order using createOrder
  • Cancelling an order that doesn't exist or doesn't belong to you will return a CANCELLATION_ERROR

Related operations: Use getUserOrders to find orders to cancel, and getBalances to see your freed balance after cancellation.

getUserOrders

Retrieve a list of your orders, optionally filtered by status. This shows all order details including amounts, prices, and current status.

Endpoint: POST https://api.silhouette.exchange/v0

Authentication: Required

Request parameters:

ParameterTypeRequiredDescription
operationstringYesMust be "getUserOrders"
statusstringNoFilter orders by status: "pending", "open", "filled", "partially_filled", "cancelled", "expired", or "failed". Omit to get all orders.

Example request (all orders):

curl https://api.silhouette.exchange/v0 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{
"operation": "getUserOrders"
}'

Example request (filtered by status):

curl https://api.silhouette.exchange/v0 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{
"operation": "getUserOrders",
"status": "open"
}'

Success response:

{
"data": {
"orders": [
{
"orderId": "550e8400-e29b-41d4-a716-446655440000",
"side": "buy",
"orderType": "limit",
"baseToken": "HYPE",
"quoteToken": "USDC",
"amount": "100000000",
"amountFloat": "100.0",
"price": "1250000",
"priceFloat": "1.25",
"status": "open",
"createdAt": 1705313400000,
"updatedAt": 1705313400000
},
{
"orderId": "650e8400-e29b-41d4-a716-446655440001",
"side": "sell",
"orderType": "market",
"baseToken": "HYPE",
"quoteToken": "USDC",
"amount": "50000000",
"amountFloat": "50.0",
"status": "filled",
"createdAt": 1705313200000,
"updatedAt": 1705313250000
}
]
},
"responseMetadata": {
"timestamp": 1705313400,
"requestId": "750e8400-e29b-41d4-a716-446655440002"
}
}

Response fields:

FieldTypeDescription
orderIdstringUnique identifier for the order
sidestringOrder side: "buy" or "sell"
orderTypestringOrder type: "limit" or "market"
baseTokenstringThe token being traded
quoteTokenstringThe token used for pricing
amountstringOrder amount in the token's smallest unit
amountFloatstringOrder amount as a human-readable decimal
pricestringOrder price (for limit orders) in scaled format
priceFloatstringOrder price as a human-readable decimal (for limit orders)
statusstringCurrent order status
createdAtnumberUnix timestamp (milliseconds) when the order was created
updatedAtnumberUnix timestamp (milliseconds) when the order was last updated

Order status values:

  • "pending": Order created but not yet processed
  • "open": Order is active and can be filled
  • "filled": Order has been completely executed
  • "partially_filled": Order has been partially executed
  • "cancelled": Order was cancelled by the user
  • "expired": Order expired before being filled
  • "failed": Order failed to process

Error responses:

{
"operation": "getUserOrders",
"error": "Invalid status filter.",
"code": "VALIDATION_ERROR",
"responseMetadata": {
"timestamp": 1705313400
}
}

Notes:

  • Orders are returned in reverse chronological order (newest first)
  • If you have no orders, the orders array will be empty
  • Both raw and float representations are provided for amounts and prices
  • Use the status filter to find specific orders (e.g., only open orders you can cancel)
  • The orderId can be used with cancelOrder to cancel an open order

Related operations: Use cancelOrder to cancel an open order, and createOrder to place new orders.

initiateWithdrawal

Request a withdrawal of funds from your Silhouette account back to your HyperCore address. Withdrawals are processed asynchronously, and you'll receive a withdrawal ID to track the status.

Endpoint: POST https://api.silhouette.exchange/v0

Authentication: Required

Request parameters:

ParameterTypeRequiredDescription
operationstringYesMust be "initiateWithdrawal"
tokenSymbolstringYesThe token to withdraw: "USDC" or "HYPE"
amountstringYesWithdrawal amount as a string (can be decimal like "100.5" or scaled integer like "100500000")

Example request:

curl https://api.silhouette.exchange/v0 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{
"operation": "initiateWithdrawal",
"tokenSymbol": "USDC",
"amount": "500.0"
}'

Success response:

{
"data": {
"message": "Withdrawal request accepted and queued for processing.",
"withdrawalId": "550e8400-e29b-41d4-a716-446655440000"
},
"responseMetadata": {
"timestamp": 1705313400,
"requestId": "650e8400-e29b-41d4-a716-446655440001"
}
}

Error responses:

{
"operation": "initiateWithdrawal",
"error": "Missing required fields: tokenSymbol and amount are required.",
"code": "VALIDATION_ERROR",
"responseMetadata": {
"timestamp": 1705313400
}
}
{
"operation": "initiateWithdrawal",
"error": "Invalid tokenSymbol. Must be 'USDC' or 'HYPE'.",
"code": "VALIDATION_ERROR",
"responseMetadata": {
"timestamp": 1705313400
}
}
{
"operation": "initiateWithdrawal",
"error": "A withdrawal request is already in progress for this user.",
"code": "CONFLICT",
"responseMetadata": {
"timestamp": 1705313400
}
}
{
"operation": "initiateWithdrawal",
"error": "The withdrawal service is temporarily unavailable. Please try again later.",
"code": "SERVICE_UNAVAILABLE",
"responseMetadata": {
"timestamp": 1705313400
}
}

Notes:

  • Withdrawals are processed asynchronously. The API returns a withdrawalId immediately, but the actual withdrawal takes time to process
  • You can only have one pending withdrawal at a time. Wait for your current withdrawal to complete before initiating another
  • The amount must not exceed your available balance (not including locked funds in open orders)
  • Amount format: Can be decimal string (e.g., "100.5") or scaled integer. Decimal values are automatically converted to the token's smallest unit
  • Use getWithdrawalStatus with the returned withdrawalId to track the withdrawal progress
  • Tokens: Currently supports "USDC" and "HYPE" only
  • Funds will be sent to your HyperCore address (the address associated with your authenticated wallet)

Related operations: Use getWithdrawalStatus to check withdrawal progress, getUserWithdrawals to view all your withdrawals, and getBalances to verify available funds.

getWithdrawalStatus

Check the status of a specific withdrawal using its withdrawal ID. This shows whether the withdrawal is still pending, has completed successfully, or has failed.

Endpoint: POST https://api.silhouette.exchange/v0

Authentication: Required

Request parameters:

ParameterTypeRequiredDescription
operationstringYesMust be "getWithdrawalStatus"
withdrawalIdstringYesThe unique identifier of the withdrawal to check

Example request:

curl https://api.silhouette.exchange/v0 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{
"operation": "getWithdrawalStatus",
"withdrawalId": "550e8400-e29b-41d4-a716-446655440000"
}'

Success response (pending):

{
"data": {
"withdrawal": {
"withdrawalId": "550e8400-e29b-41d4-a716-446655440000",
"token": "USDC",
"amount": "500000000",
"state": "pending",
"txHash": null,
"errorMessage": null,
"created_at": 1705313400000,
"updated_at": 1705313400000
}
},
"responseMetadata": {
"timestamp": 1705313450,
"requestId": "650e8400-e29b-41d4-a716-446655440001"
}
}

Success response (completed):

{
"data": {
"withdrawal": {
"withdrawalId": "550e8400-e29b-41d4-a716-446655440000",
"token": "USDC",
"amount": "500000000",
"state": "completed",
"txHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
"errorMessage": null,
"created_at": 1705313400000,
"updated_at": 1705313500000
}
},
"responseMetadata": {
"timestamp": 1705313550,
"requestId": "750e8400-e29b-41d4-a716-446655440002"
}
}

Success response (failed):

{
"data": {
"withdrawal": {
"withdrawalId": "550e8400-e29b-41d4-a716-446655440000",
"token": "USDC",
"amount": "500000000",
"state": "failed",
"txHash": null,
"errorMessage": "Insufficient balance on enclave wallet",
"created_at": 1705313400000,
"updated_at": 1705313450000
}
},
"responseMetadata": {
"timestamp": 1705313500,
"requestId": "850e8400-e29b-41d4-a716-446655440003"
}
}

Response fields:

FieldTypeDescription
withdrawalIdstringUnique identifier for the withdrawal
tokenstringThe token symbol being withdrawn
amountstringWithdrawal amount in the token's smallest unit
statestringWithdrawal status: "pending", "completed", or "failed"
txHashstring | nullTransaction hash on Hyperliquid (only set when state is "completed")
errorMessagestring | nullError description (only set when state is "failed")
created_atnumberUnix timestamp (milliseconds) when the withdrawal was created
updated_atnumberUnix timestamp (milliseconds) when the withdrawal was last updated

Withdrawal states:

  • "pending": Withdrawal is queued and being processed
  • "completed": Withdrawal was successful. Check txHash for the transaction details
  • "failed": Withdrawal failed. Check errorMessage for the reason

Error responses:

{
"operation": "getWithdrawalStatus",
"error": "Missing or invalid withdrawalId.",
"code": "VALIDATION_ERROR",
"responseMetadata": {
"timestamp": 1705313400
}
}
{
"operation": "getWithdrawalStatus",
"error": "Withdrawal not found.",
"code": "NOT_FOUND",
"responseMetadata": {
"timestamp": 1705313400
}
}

Notes:

  • You can only query your own withdrawals. Attempting to check another user's withdrawal returns NOT_FOUND
  • Poll this endpoint periodically to track withdrawal progress
  • When state is "completed", use the txHash to verify the transaction on the Hyperliquid blockchain
  • When state is "failed", check the errorMessage to understand why the withdrawal failed
  • The withdrawalId is returned when you call initiateWithdrawal

Related operations: Use initiateWithdrawal to request a withdrawal, and getUserWithdrawals to view all your withdrawals.

getUserWithdrawals

Retrieve a list of all your withdrawal requests, including their current status. This provides a complete history of your withdrawals.

Endpoint: POST https://api.silhouette.exchange/v0

Authentication: Required

Request parameters:

ParameterTypeRequiredDescription
operationstringYesMust be "getUserWithdrawals"

Example request:

curl https://api.silhouette.exchange/v0 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{
"operation": "getUserWithdrawals"
}'

Success response:

{
"data": {
"withdrawals": [
{
"withdrawalId": "650e8400-e29b-41d4-a716-446655440001",
"token": "USDC",
"amount": "500000000",
"state": "completed",
"txHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
"errorMessage": null,
"created_at": 1705313400000,
"updated_at": 1705313500000
},
{
"withdrawalId": "550e8400-e29b-41d4-a716-446655440000",
"token": "HYPE",
"amount": "100000000",
"state": "pending",
"txHash": null,
"errorMessage": null,
"created_at": 1705313200000,
"updated_at": 1705313200000
},
{
"withdrawalId": "450e8400-e29b-41d4-a716-446655440002",
"token": "USDC",
"amount": "250000000",
"state": "failed",
"txHash": null,
"errorMessage": "Insufficient balance on enclave wallet",
"created_at": 1705313000000,
"updated_at": 1705313050000
}
]
},
"responseMetadata": {
"timestamp": 1705313600,
"requestId": "750e8400-e29b-41d4-a716-446655440003"
}
}

Response fields:

Each withdrawal in the array has the following fields:

FieldTypeDescription
withdrawalIdstringUnique identifier for the withdrawal
tokenstringThe token symbol being withdrawn
amountstringWithdrawal amount in the token's smallest unit
statestringWithdrawal status: "pending", "completed", or "failed"
txHashstring | nullTransaction hash on Hyperliquid (only set when state is "completed")
errorMessagestring | nullError description (only set when state is "failed")
created_atnumberUnix timestamp (milliseconds) when the withdrawal was created
updated_atnumberUnix timestamp (milliseconds) when the withdrawal was last updated

Error responses:

{
"operation": "getUserWithdrawals",
"error": "An internal error occurred while fetching withdrawals.",
"code": "INTERNAL_ERROR",
"responseMetadata": {
"timestamp": 1705313400
}
}

Notes:

  • Withdrawals are returned in reverse chronological order (newest first)
  • If you have no withdrawals, the withdrawals array will be empty
  • Use this to get an overview of all your withdrawal activity
  • Each withdrawal includes the same fields as getWithdrawalStatus
  • Amount values are in the token's smallest unit (for USDC, micro-USDC)

Related operations: Use initiateWithdrawal to create a new withdrawal, and getWithdrawalStatus to check the status of a specific withdrawal.