---
title: "Create a list (keyless draft + claim URL, or directly in the connected account)"
method: POST
path: "/api/v1/agent/lists"
tags: ["lists"]
---

# Create a list (keyless draft + claim URL, or directly in the connected account)

`POST /api/v1/agent/lists`

## Request

- Base URL: `https://www.listdrop.co`
- URL: `https://www.listdrop.co/api/v1/agent/lists`
- Auth: one of:
  - none
  - OAuth 2 (authorization code, authorization URL `https://www.listdrop.co/oauth/authorize`, token URL `https://www.listdrop.co/api/oauth/token`, scopes: `lists:write`)

Creates a list from list-shaped content the user will want to keep: an itinerary, a reading or watch list, a packing list, gift ideas, an apartment or job-search shortlist, a step-by-step plan, a checklist. The test: would the user want this list after the conversation ends? The list is born PRIVATE and unowned; the response's claimUrl is the only way to view and keep it. Show the claim URL to the user and treat it like a password. Unclaimed drafts expire in 30 days. Items that contain a URL are unfurled into titled, linked items. CORS-open. Rate limits: 50 per hour and 300 per day per IP. With an OAuth bearer token carrying lists:write, the list is instead created directly in the user's account (private, no claim URL; response has url instead of claimUrl) and limits are per user. Optional extras: allowed_emails email-gates the private list for specific viewers (see the schema), expires_in_days makes it self-archive.

## Request body

- CreateListRequest
  - `title` string, required
  - `emoji` string: Optional single emoji for the list.
  - `description` string
  - `tags` string[]: Topic tags, plain words (books, travel).
  - `items` ListItemInput[], required
    - union
      - string: Item text; a URL inside is unfurled.
      - object
        - `text` string, required
        - `note` string: Short note shown under the item.
  - `allowed_emails` string[]: Optional email gate: these addresses can VIEW the private list at its URL after verifying the address via a mailed one-time link — no ListDrop account needed. View-only; omit for the classic unlisted claim-link behavior.
  - `expires_in_days` integer: Optional self-archive: after this many days the list becomes visible to its owner only (public lists unpublish, email gates close).

## Response `201`

Created. Keyless: a draft with claimUrl. OAuth: an owned private list with url.

- CreateListResponse
  - `id` string, required: List id.
  - `claimUrl` string, uri: Keyless flow only. Secret URL: the only way to view and keep the list. Show it to the user only.
  - `url` string, uri: OAuth flow only: the created list's page in the user's account.
  - `expiresAt` integer: Keyless flow only: unix ms after which an unclaimed draft is purged.
  - `shareUrl` string, uri: Present when allowed_emails was set (keyless flow): the URL the allowlisted people open — share THIS with them, never the claim URL.
  - `allowedEmails` string[]: Echo of the accepted (normalized) guest list, when allowed_emails was set.
  - `message` string, required: Instructions to relay to the user.

## Other responses

- `400`: Invalid body (missing title, empty or oversized items).
- `401`: Bearer token invalid/expired, or missing the lists:write scope.
- `429`: Per-IP rate limit hit. Honor Retry-After; do not create duplicates.
- `503`: Creation temporarily paused (global cap). Retry later.

---

[API](https://skmtc.dev/listdrop/apis/listdrop-public-api.md) · [All operations](https://skmtc.dev/listdrop/apis/listdrop-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/listdrop/apis/listdrop-public-api/revisions/699b5367e2f3?raw)
