POST /api/v1/listings
Create a new marketplace listing. The seller address must match the authenticated user. On creation, background jobs are queued for expiry scheduling, ENS metadata sync, and club floor price updates.
Authentication: Required
Cache: None
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
ensNameId | number | Yes | Database ID of the ENS name |
sellerAddress | string | Yes | Seller’s Ethereum address (must match authenticated user) |
priceWei | string | Yes | Listing price in wei |
currencyAddress | string | No | Payment token address (defaults to ETH zero address) |
orderData | any | Yes | Seaport order data for on-chain fulfillment |
expiresAt | string | No | Listing expiration date (ISO string) |
Sample Request
curl -X POST -H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
https://api.grails.app/api/v1/listings \
-d '{
"ensNameId": 1,
"sellerAddress": "0xabcd...",
"priceWei": "100000000000000000",
"orderData": { ... }
}'Response
// 201 Created
{
"success": true,
"data": {
"id": 43,
"ens_name_id": 1,
"seller_address": "0xabcd...",
"price_wei": "100000000000000000",
"currency_address": "0x0000000000000000000000000000000000000000",
"order_hash": null,
"order_data": { ... },
"status": "active",
"source": null,
"created_at": "2026-04-07T12:00:00.000Z",
"updated_at": "2026-04-07T12:00:00.000Z",
"expires_at": null,
"broker_address": null,
"broker_fee_bps": null
},
"meta": {
"timestamp": "2026-04-07T12:00:00.000Z",
"version": "1.0.0"
}
}Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid request body |
| 401 | UNAUTHORIZED | Missing or invalid token |
| 403 | FORBIDDEN | Seller address does not match authenticated user |
| 404 | ENS_NAME_NOT_FOUND | ENS name ID does not exist |
Last updated on