API Reference
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:
| Parameter | Type | Required | Description |
|---|---|---|---|
| operation | string | Yes | Must be "login" |
| message | string | Yes | The SIWE message to verify. Must include the statement "Sign in with Ethereum to the app." |
| signature | string | Yes | The 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
Authorizationheader 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:
| Parameter | Type | Required | Description |
|---|---|---|---|
| operation | string | Yes | Must 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:
| Field | Type | Description |
|---|---|---|
| token | string | The token symbol (e.g., "USDC") |
| available | string | Available balance in the token's smallest unit (can be used for trading or withdrawal) |
| availableFloat | string | Available balance as a human-readable decimal number |
| locked | string | Balance locked in open orders, in the token's smallest unit |
| lockedFloat | string | Locked balance as a human-readable decimal number |
| total | string | Total balance (available + locked), in the token's smallest unit |
| totalFloat | string | Total 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
lockedfield shows funds currently reserved in open orders and unavailable for new trades or withdrawals - The
availablefield 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
Authorizationheader
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:
| Parameter | Type | Required | Description |
|---|---|---|---|
| operation | string | Yes | Must be "createOrder" |
| side | string | Yes | Order side: "buy" or "sell" |
| orderType | string | Yes | Order type: "limit" or "market" |
| baseToken | string | Yes | The token being traded: "USDC" or "HYPE" |
| quoteToken | string | Yes | The token used for pricing: "USDC" or "HYPE" |
| amount | string | Yes | Order amount as a string (can be decimal like "100.5" or scaled integer like "100500000") |
| price | string | Conditional | Order 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 thepriceparameter."market": Order executes immediately at the best available price. Thepriceparameter 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
orderIdto 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:
| Parameter | Type | Required | Description |
|---|---|---|---|
| operation | string | Yes | Must be "cancelOrder" |
| orderId | string | Yes | The 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
orderIdis returned when you create an order usingcreateOrder - 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:
| Parameter | Type | Required | Description |
|---|---|---|---|
| operation | string | Yes | Must be "getUserOrders" |
| status | string | No | Filter 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:
| Field | Type | Description |
|---|---|---|
| orderId | string | Unique identifier for the order |
| side | string | Order side: "buy" or "sell" |
| orderType | string | Order type: "limit" or "market" |
| baseToken | string | The token being traded |
| quoteToken | string | The token used for pricing |
| amount | string | Order amount in the token's smallest unit |
| amountFloat | string | Order amount as a human-readable decimal |
| price | string | Order price (for limit orders) in scaled format |
| priceFloat | string | Order price as a human-readable decimal (for limit orders) |
| status | string | Current order status |
| createdAt | number | Unix timestamp (milliseconds) when the order was created |
| updatedAt | number | Unix 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
ordersarray will be empty - Both raw and float representations are provided for amounts and prices
- Use the
statusfilter to find specific orders (e.g., only open orders you can cancel) - The
orderIdcan be used withcancelOrderto 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:
| Parameter | Type | Required | Description |
|---|---|---|---|
| operation | string | Yes | Must be "initiateWithdrawal" |
| tokenSymbol | string | Yes | The token to withdraw: "USDC" or "HYPE" |
| amount | string | Yes | Withdrawal 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
withdrawalIdimmediately, 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
getWithdrawalStatuswith the returnedwithdrawalIdto 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:
| Parameter | Type | Required | Description |
|---|---|---|---|
| operation | string | Yes | Must be "getWithdrawalStatus" |
| withdrawalId | string | Yes | The 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:
| Field | Type | Description |
|---|---|---|
| withdrawalId | string | Unique identifier for the withdrawal |
| token | string | The token symbol being withdrawn |
| amount | string | Withdrawal amount in the token's smallest unit |
| state | string | Withdrawal status: "pending", "completed", or "failed" |
| txHash | string | null | Transaction hash on Hyperliquid (only set when state is "completed") |
| errorMessage | string | null | Error description (only set when state is "failed") |
| created_at | number | Unix timestamp (milliseconds) when the withdrawal was created |
| updated_at | number | Unix timestamp (milliseconds) when the withdrawal was last updated |
Withdrawal states:
"pending": Withdrawal is queued and being processed"completed": Withdrawal was successful. ChecktxHashfor the transaction details"failed": Withdrawal failed. CheckerrorMessagefor 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
stateis"completed", use thetxHashto verify the transaction on the Hyperliquid blockchain - When
stateis"failed", check theerrorMessageto understand why the withdrawal failed - The
withdrawalIdis returned when you callinitiateWithdrawal
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:
| Parameter | Type | Required | Description |
|---|---|---|---|
| operation | string | Yes | Must 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:
| Field | Type | Description |
|---|---|---|
| withdrawalId | string | Unique identifier for the withdrawal |
| token | string | The token symbol being withdrawn |
| amount | string | Withdrawal amount in the token's smallest unit |
| state | string | Withdrawal status: "pending", "completed", or "failed" |
| txHash | string | null | Transaction hash on Hyperliquid (only set when state is "completed") |
| errorMessage | string | null | Error description (only set when state is "failed") |
| created_at | number | Unix timestamp (milliseconds) when the withdrawal was created |
| updated_at | number | Unix 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
withdrawalsarray 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.