Orders
Place, sign, and cancel orders on the matching engine. Retail users sign orders via the Privy session signer.
Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/orders/nonce | Request order nonce |
POST | /api/orders/ | Create order |
POST | /api/orders/cancel | Cancel order |
Request order nonce
POST /api/orders/nonce
Issues a one-time nonce before the client signs an order payload (anti-replay).
Request
import axios from 'axios';
const response = await axios.post('https://api.loafmarkets.com/api/orders/nonce', undefined, {
headers: { Authorization: `Bearer ${process.env.LOAF_PRIVY_JWT}` },
});
console.log(response.data);Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| None | - | No | No parameters for this endpoint. |
Response
Type: OrderNonceResponse
interface OrderNonceResponse {
nonce: string;
deadline: number; // Unix seconds
}Example response:
{
"nonce": "a1b2c3d4e5f6789012345678901234ab",
"deadline": 1893456000
}Errors
| Status | Code | Description |
|---|---|---|
400 | validation_error | Request failed schema validation. |
401 | unauthorized | Missing or invalid authentication. |
404 | not_found | Resource not found (where applicable). |
500 | internal_error | Unexpected server error. |
Requires Privy JWT authentication.
Create order
POST /api/orders/
Submits a session-signer-signed order for the authenticated retail user.
Request body
Type: OrderRequestBody (@loafmarkets/shared-types)
interface OrderRequestBody {
propertyId: number;
price: number;
quantity: number;
side: 'BUY' | 'SELL';
type: 'MARKET' | 'LIMIT';
timeInForce: 'GTC' | 'IOC' | 'FOK' | 'GTD';
deadline: number;
nonce: string;
}Order payload is signed by the Privy session signer before submission.
Request
import axios from 'axios';
import type { OrderRequestBody } from '@loafmarkets/shared-types';
const body: OrderRequestBody = {
propertyId: 42,
price: 125.5,
quantity: 10,
side: 'BUY',
type: 'LIMIT',
timeInForce: 'GTC',
deadline: 0,
nonce: 'a1b2c3d4e5f6789012345678901234ab',
};
const response = await axios.post('https://api.loafmarkets.com/api/orders/', body, {
headers: { Authorization: `Bearer ${process.env.LOAF_PRIVY_JWT}` },
});
console.log(response.data);Retail orders must be signed with the Privy session signer before submission. The curl above shows the HTTP request shape; use the Loaf client SDK or your app’s signer in production. For a market order, set "type": "MARKET" and "price": 0.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
propertyId | number | Yes | (body) Property ID (positive integer). |
price | number | Yes | (body) Limit price in USDL. Use 0 for market orders (MARKET_ORDER_PRICE). |
quantity | number | Yes | (body) Order size in tokens (max 1 decimal place). |
side | 'BUY' | 'SELL' | Yes | (body) Order side. |
type | 'MARKET' | 'LIMIT' | Yes | (body) Order type. |
timeInForce | 'GTC' | 'IOC' | 'FOK' | 'GTD' | Yes | (body) Time in force. |
deadline | number | Yes | (body) Unix timestamp (seconds). Use 0 unless timeInForce is GTD. |
nonce | string | Yes | (body) 32-character hex nonce from POST /api/orders/nonce. |
Response
Type: OrderApiResponse
interface OrderApiResponse {
success: boolean;
orderId: number;
errorMessage?: string;
}Example response:
{
"success": true,
"orderId": 9001
}Errors
| Status | Code | Description |
|---|---|---|
400 | validation_error | Request failed schema validation. |
401 | unauthorized | Missing or invalid authentication. |
404 | not_found | Resource not found (where applicable). |
500 | internal_error | Unexpected server error. |
Requires Privy JWT authentication.
Cancel order
POST /api/orders/cancel
Cancels an existing order via the matching engine.
Request body
Type: CancelOrderRequestBody (@loafmarkets/shared-types)
interface CancelOrderRequestBody {
orderId: number;
}Request
import axios from 'axios';
import type { CancelOrderRequestBody } from '@loafmarkets/shared-types';
const body: CancelOrderRequestBody = {
orderId: 9001,
};
const response = await axios.post('https://api.loafmarkets.com/api/orders/cancel', body, {
headers: { Authorization: `Bearer ${process.env.LOAF_PRIVY_JWT}` },
});
console.log(response.data);Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
orderId | number | Yes | (body) ID of the order to cancel. |
Response
Type: CancelOrderResponse
interface CancelOrderResponse {
success: boolean;
orderId: number;
errorMessage?: string;
}Example response:
{
"success": true,
"orderId": 9001
}Errors
| Status | Code | Description |
|---|---|---|
400 | validation_error | Request failed schema validation. |
401 | unauthorized | Missing or invalid authentication. |
404 | not_found | Resource not found (where applicable). |
500 | internal_error | Unexpected server error. |
Requires Privy JWT authentication.