Listings

Listings

GETPOST · PATCH · DELETE

Browse the live marketplace publicly. With a sandbox key, list and manage only your sandbox inventory. Write routes require scope listings:write (included on new keys by default).

Environment isolation

  • Anonymous / live key on GET /listings → public live active feed (same as Discover).
  • Sandbox key on GET /listingsyour sandbox listings only (never the live marketplace).
  • Sandbox listings never appear on public Discover.

GET /listings

Cursor pagination. Newest published_at first.

QueryTypeDefaultNotes
limitint241–100
cursorstringISO published_at of last item (exclusive, older)
curl — public live feed
curl -sS "https://www.threadzsocial.com/api/v1/listings?limit=10"

curl -sS "https://www.threadzsocial.com/api/v1/listings?limit=10&cursor=2026-07-01T12:00:00.000Z"
curl — sandbox own inventory
curl -sS "https://www.threadzsocial.com/api/v1/listings?limit=10" \
  -H "Authorization: Bearer stz_sandbox_YOUR_KEY"
Response shape (live card)
{
  "data": [
    {
      "id": "uuid",
      "title": "Vintage denim jacket",
      "description": "…",
      "category": "Women",
      "condition": "good",
      "price_cents": 4500,
      "currency": "usd",
      "status": "active",
      "impact_mode": false,
      "cover_image_url": "https://…",
      "like_count": 3,
      "published_at": "2026-07-18T12:00:00.000Z",
      "seller": {
        "id": "uuid",
        "username": "jane",
        "display_name": "Jane",
        "avatar_url": null
      }
    }
  ],
  "meta": {
    "version": "v1",
    "environment": "live",
    "next_cursor": "2026-07-18T11:00:00.000Z",
    "count": 10
  }
}

GET /listings/{id}

Single listing by UUID. Isolation: anonymous sees live active; sandbox key sees own sandbox rows; live key sees live active (or own live any status).

curl — detail
curl -sS "https://www.threadzsocial.com/api/v1/listings/00000000-0000-0000-0000-000000000001"

Errors: 400 validation_error · 404 not_found · 503 service_unavailable

POST /listings — create

Requires Bearer + scope listings:write. Creates in the key's environment (sandbox or live). With external_id (body) or an Idempotency-Key header, repeats are idempotent upserts (same seller + env + key).

Idempotency-Key

Send Idempotency-Key: <your-key> on create. The value is stored as external_id (unique per seller + environment). Retries with the same key return the same listing (200 upsert, not a duplicate). You may set the same value in the JSON body as external_id instead of — or equal to — the header. If both are present and differ, the API returns 400 validation_error. There is no separate idempotency store beyond external_id.

FieldTypeRequiredNotes
titlestringyes3–120 chars
price_cents or price_dollarsnumberyes (one)Positive; not both
descriptionstring | nullnomax 5000
category / brand / size / colorstring | nullnomax 80
conditionenum | nullnonew_with_tags, new_without_tags, excellent, like_new, good, fair, poor
tagsstring[]nomax 20 × 40 chars
statusenumnodraft (default) or active
cover_image_url / image_urlsurl / url[]for activeAt least one photo when active; max 16
external_idstringnoYour system id; unique per seller + environment. Same role as Idempotency-Key
curl — create (sandbox)
curl -sS -X POST https://www.threadzsocial.com/api/v1/listings \
  -H "Authorization: Bearer stz_sandbox_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: erp-sku-1001" \
  -d '{
    "title": "API test linen shirt",
    "price_cents": 2800,
    "description": "Sandbox listing — safe to delete",
    "category": "Women",
    "condition": "good",
    "status": "draft",
    "tags": ["sandbox", "api"]
  }'

Response 201 when created, 200 when upserted via external_id / Idempotency-Key. meta.environment echoes the key environment; meta.idempotency_key is present when the header was sent. Completing a sandbox create advances the sandbox_listing go-live milestone.

POST /listings/batch — bulk upsert

Create or upsert up to 25 listings in one request. Same auth and fields as POST /listings for each item. Useful for ERP/PoshTrack sync. Sandbox results show in Sandbox Hub.

curl — batch
curl -sS -X POST https://www.threadzsocial.com/api/v1/listings/batch \
  -H "Authorization: Bearer stz_sandbox_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "title": "Item A", "price_cents": 2000, "external_id": "a-1", "status": "draft" },
      { "title": "Item B", "price_cents": 3000, "external_id": "b-1", "status": "draft" }
    ]
  }'

Response data.results[] is per-index success or error. Meta: total, created, updated, failed, max_per_request (25). HTTP 200 if any succeed; 422 if all fail.

PATCH /listings/{id} — update

Partial update. Owner + same environment + listings:write. All body fields optional.

curl — patch
curl -sS -X PATCH https://www.threadzsocial.com/api/v1/listings/LISTING_UUID \
  -H "Authorization: Bearer stz_sandbox_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Updated title",
    "price_cents": 2600,
    "status": "active",
    "cover_image_url": "https://example.com/photo.jpg",
    "image_urls": ["https://example.com/photo.jpg"]
  }'

DELETE /listings/{id} — archive

Soft-archive: sets status = archived. Owner + listings:write. Returns the archived listing resource.

curl — delete
curl -sS -X DELETE https://www.threadzsocial.com/api/v1/listings/LISTING_UUID \
  -H "Authorization: Bearer stz_sandbox_YOUR_KEY"

Write errors

CodeHTTPWhen
unauthorized401Missing/invalid key
forbidden403Missing listings:write or not owner
validation_error400Bad body / active without photos
not_found404Unknown id or wrong environment
rate_limited429Too many requests

Create keys on your apps. Envelope details: Errors. Closets: Closets & me.