LiftOff API

Public API for LiftOff products. Versioned routes live under /v1/. Trailing slash paths are canonical, but non-trailing aliases also work.

Auth

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.

API access and usage limits

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.

Response envelopes

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.

Route summary

MethodPathAuth / scopePurpose
GET/public; no API key or scopeStatic API documentation page
GET/v1/ping/valid API key; no specific scopeHealth/token check
GET/v1/get-product/productReadGet one product by slug or id
GET/v1/list-products/productListList products with pagination
GET/v1/get-next-free-window/productCreateFind next available free/featured launch day
POST/v1/create-product/productCreateCreate a product with multipart WebP uploads

GET /

Public static HTML documentation page.

AuthPublic; no API key or scope
ParamsNone
Response200 text/html

GET /v1/ping/

Checks that the API is reachable and the API token is valid.

AuthValid API key; no specific scope
ParamsNone

200 response

{
  "ok": true,
  "service": "lift-off-api",
  "version": 1,
  "status": "healthy"
}

GET /v1/get-product/

Gets one product. Pass exactly one of id or slug.

Query paramRequiredRules
idone of id/slugProduct ID, max 36 bytes
slugone of id/slugmax 32 bytes; lowercase letters, numbers, -, _; cannot start/end with separator
AuthproductRead

200 response

{
  "ok": true,
  "product": { ...product fields... }
}

Typical errors: validation_error, product_not_found, scope_denied.

GET /v1/list-products/

Lists products with bounded pagination.

Query paramDefaultRules
limit20integer 1..100
offset0integer 0..10000
sortlaunchDatelaunchDate, upvoteCount, or fuelCount
orderdescasc or desc
AuthproductList

200 response

{
  "ok": true,
  "total": 123,
  "limit": 20,
  "offset": 0,
  "products": [ { ...product fields... } ]
}

Typical errors: validation_error, scope_denied.

GET /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 paramRequiredRules
planyesfree or featured
AuthproductCreate

Launch-window availability is subject to current scheduling limits.

200 response

{
  "ok": true,
  "plan": "free",
  "launchDate": "2026-08-20T00:00:00.000+00:00"
}

Typical errors: validation_error, launch_window_unavailable, scope_denied.

POST /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.

AuthproductCreate

Required text fields

FieldRules
name1–32 characters.
urlvalid http or https URL
tagline1–128 characters
description1–4096 characters
planfree, featured, boost, or all-in
launchDatetomorrow or later at UTC midnight, for example 2026-08-20T00:00:00.000+00:00. free/featured dates must have an available slot.

Optional text fields

FieldRules
codeUrlvalid http or https URL
pricingModelnone, free, freemium, or paid
twitterTagmax 64 characters
blueskyTagmax 128 characters
dealCodemax 32 characters
dealExpireISO 8601/RFC 3339 datetime

Required file fields

Unknown fields are rejected. Empty optional text fields are rejected; omit unused optional fields.

Example multipart 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

201 response

{
  "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 response fields

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.

Audit logging

Every request with a valid API key is written to the API audit log and can be viewed in the dashboard.