The Maker API
Add and update your Listings from a script or an agent, with the same fields the Editor has. A new Listing always lands as a Draft; publishing stays within your Listing cap.
Your token
Send your token with every call. Each Maker has one; rotating it ends the old one at once.
Authorization: Bearer YOUR_TOKEN
Up to 60 calls a minute. Your token only ever reaches your own Catalog.
The package
A Listing travels as one JSON file plus its media. The API reads and returns the same shape, so a package you fetch can be sent straight back.
| FIELD | TYPE | NOTE |
|---|---|---|
slug | string | Unique within your Catalog. Becomes overnighters.app/@you/apps/slug. |
kind | external | Always external for Makers. Only the Operator’s apps are Hosted. |
external_url | url | Where the Listing runs. |
category | key | One key from the shared Categories. |
name_en | string | Words need at least English or Spanish; the other falls back. |
name_es | string | Same rule as name_en. |
tagline_en | string | Up to 70 characters. |
tagline_es | string | Up to 70 characters. |
description_en | text | Plain text. A blank line starts a paragraph. |
description_es | text | Plain text. A blank line starts a paragraph. |
tags | array | A list of short words. |
ships_in | array | Languages the Listing itself speaks: es, en. |
tech_stack | string | Free text. |
launched_on | date | YYYY-MM-DD. |
for_sale | boolean | Opens the Purchase-interest Inquiry. |
asking_price | integer | Whole US dollars. Leave out for Open to offers. |
featured | boolean | At most one per Catalog; featuring one replaces the last. |
acquired | boolean | For External apps that changed hands. |
status | draft|published|retired | Ignored on create. On update: draft, published or retired. A Listing must be complete to publish. |
retired_mode | farewell|redirect | farewell (the default) or redirect. Used when status is retired. |
redirect_url | url | Where visitors go after a redirect retirement. |
Media
Send files as multipart parts named cover, shot-1, shot-2, shot-3, loop. Images up to 10 MB; the loop is a short silent MP4 or WebM.
{
"slug": "lonchera",
"kind": "external",
"external_url": "https://lonchera.app",
"category": "kitchen",
"name_en": "Lonchera",
"tagline_en": "A week of school lunches, planned on Sunday.",
"tagline_es": "Una semana de loncheras, planeada el domingo.",
"ships_in": ["es", "en"],
"for_sale": true,
"asking_price": 1200
}
Endpoints
GET/maker/api/listings/:slug
Returns the package of one of your Listings, with media URLs.
curl https://overnighters.app/maker/api/listings/lonchera \
-H "Authorization: Bearer $OVERNIGHTERS_TOKEN"
POST/maker/api/listings
Creates a Draft from a package and its files. It never publishes.
curl https://overnighters.app/maker/api/listings \
-H "Authorization: Bearer $OVERNIGHTERS_TOKEN" \
-F "package=@lonchera/package.json;type=application/json" \
-F "cover=@lonchera/cover.png" \
-F "shot-1=@lonchera/shot-1.png" \
-F "loop=@lonchera/loop.mp4"
PATCH/maker/api/listings/:slug
Changes only the fields and files you send. Send status published to publish.
curl -X PATCH https://overnighters.app/maker/api/listings/lonchera \
-H "Authorization: Bearer $OVERNIGHTERS_TOKEN" \
-F 'package={"asking_price": 900, "status": "published"};type=application/json'
When something is wrong
400- There is no package, or it isn’t valid JSON.
401- No token, a token that was rotated, or a suspended account.
403- You’re at your Listing cap, so this Listing can’t be published. Drafts still save; unpublish or retire a Listing, or ask for more room.
404- No Listing with that slug in your Catalog.
409- The slug is taken in your Catalog. The body holds the existing package, so you can compare.
422- The package doesn’t validate. The body says what is wrong.
429- Too many calls. Wait a minute.