Public API for LiftOff products. Versioned routes live under /v1/. Trailing slash paths are canonical, but non-trailing aliases also work.
All /v1/ routes require a valid API token. Pass exactly one token header:
Authorization: Bearer <api-token> X-API-Token: <api-token>
Do not send both headers. The public GET / documentation page does not require auth.
Available API access plans and their current usage limits may change. See the official API pricing page for the current details.
Only successful (2xx) responses consume total usage; successful get-product and list-products responses consume their corresponding get or list usage.
A get query retrieves one resource and is identified by a route requiring a *Read scope; in the currently documented routes, /v1/get-product/ is a get query. A list query retrieves a collection and is identified by a route requiring a *List scope; currently /v1/list-products/ is a list query. Both also count toward the total API-call allowance. Other routes count toward total calls and any separately stated launch allowance.
Success responses include ok: true. Errors use this shape:
{ "ok": false, "code": "error_code", "message": "Human-readable message." }
Common error codes include auth_invalid, auth_ambiguous, plan_not_allowed, scope_denied, validation_error, usage_limit_exceeded, service_error, not_found, and method_not_allowed.
| Method | Path | Auth / scope | Purpose |
|---|---|---|---|
| GET | / | public; no API key or scope | Static API documentation page |
| GET | /v1/ping/ | valid API key; no specific scope | Health/token check |
| GET | /v1/get-product/ | productRead | Get one product by slug or id |
| GET | /v1/list-products/ | productList | List products with pagination |
| GET | /v1/get-next-free-window/ | productCreate | Find next available free/featured launch day |
| POST | /v1/create-product/ | productCreate | Create a product with multipart WebP uploads |
/Public static HTML documentation page.
| Auth | Public; no API key or scope |
|---|---|
| Params | None |
| Response | 200 text/html |
/v1/ping/Checks that the API is reachable and the API token is valid.
| Auth | Valid API key; no specific scope |
|---|---|
| Params | None |
{
"ok": true,
"service": "lift-off-api",
"version": 1,
"status": "healthy"
}
/v1/get-product/Gets one product. Pass exactly one of id or slug.
| Query param | Required | Rules |
|---|---|---|
id | one of id/slug | Product ID, max 36 bytes |
slug | one of id/slug | max 32 bytes; lowercase letters, numbers, -, _; cannot start/end with separator |
| Auth | productRead |
|---|
{
"ok": true,
"product": { ...product fields... }
}
Typical errors: validation_error, product_not_found, scope_denied.
/v1/list-products/Lists products with bounded pagination.
| Query param | Default | Rules |
|---|---|---|
limit | 20 | integer 1..100 |
offset | 0 | integer 0..10000 |
sort | launchDate | launchDate, upvoteCount, or fuelCount |
order | desc | asc or desc |
| Auth | productList |
|---|
{
"ok": true,
"total": 123,
"limit": 20,
"offset": 0,
"products": [ { ...product fields... } ]
}
Typical errors: validation_error, scope_denied.
/v1/get-next-free-window/Returns the next UTC midnight launch day with remaining slots. This is advisory; create-product can still fail if another request reserves the last slot first.
| Query param | Required | Rules |
|---|---|---|
plan | yes | free or featured |
| Auth | productCreate |
|---|
Launch-window availability is subject to current scheduling limits.
{
"ok": true,
"plan": "free",
"launchDate": "2026-08-20T00:00:00.000+00:00"
}
Typical errors: validation_error, launch_window_unavailable, scope_denied.
/v1/create-product/Creates and immediately publishes a product. Request body must be multipart/form-data; do not manually set the multipart boundary in browser clients.
| Auth | productCreate |
|---|
| Field | Rules |
|---|---|
name | 1–32 characters. |
url | valid http or https URL |
tagline | 1–128 characters |
description | 1–4096 characters |
plan | free, featured, boost, or all-in |
launchDate | tomorrow or later at UTC midnight, for example 2026-08-20T00:00:00.000+00:00. free/featured dates must have an available slot. |
| Field | Rules |
|---|---|
codeUrl | valid http or https URL |
pricingModel | none, free, freemium, or paid |
twitterTag | max 64 characters |
blueskyTag | max 128 characters |
dealCode | max 32 characters |
dealExpire | ISO 8601/RFC 3339 datetime |
logo: exactly one non-animated WebP, max 5,000,000 bytes.screenshots: 1–10 non-animated WebP files, max 5,000,000 bytes each.Unknown fields are rejected. Empty optional text fields are rejected; omit unused optional fields.
name=Example url=https://example.com tagline=A short product tagline description=Longer product description. plan=free launchDate=2026-08-20T00:00:00.000+00:00 logo=@logo.webp;type=image/webp screenshots=@screenshot-1.webp;type=image/webp
{
"ok": true,
"product": { ...product fields... }
}
Typical errors: multipart_required, validation_error, file_too_large, file_conflict, product_conflict, launch_window_full, product_rejected, scope_denied.
Product responses include id, optional createdAt/updatedAt, and product data fields. Products created through this API include:
{
"id": "example",
"name": "Example",
"url": "https://example.com",
"tagline": "A short product tagline",
"description": "Longer product description.",
"slug": "example",
"plan": "free",
"launchDate": "2026-08-20T00:00:00.000+00:00",
"logo": "file-id",
"screenshots": ["file-id"]
}
Optional product fields can include codeUrl, pricingModel, twitterTag, blueskyTag, dealCode, and dealExpire. Some older products may include additional fields.
Every request with a valid API key is written to the API audit log and can be viewed in the dashboard.