Getting started
QuickstartConceptsRecommended setupsAuthenticationAPIs
Delivery APIOutbound webhooksLogsIngest webhookImagesErrorsLibraries
TypeScript SDKReference
Plans and limitsDelivery API
Endpoints for reading published articles.
https://api.coppercms.com/v1
List articles
GET /v1/wire/posts authorization: Bearer ck_a41f…
| Parameter | What it does | Default |
|---|---|---|
| limit | How many to return. Maximum 100. | 20 |
| cursor | Fetch the next page. Taken from nextCursor. | |
| tag | Only articles carrying this tag. | |
| since | Only articles published at or after this time. | |
| q | Full text search over the title and the body. |
{
"data": [ … ],
"nextCursor": "MjAyNi0wOC0yOVQwOTowMDowMFp8NWMwZg"
}
Articles come back newest first. nextCursor is null on the last page.
Fetch an article
GET /v1/wire/posts/a-new-office-in-lisbon authorization: Bearer ck_a41f…
The article comes back under data. A slug that is not published on this site answers 404.
A slug belongs to the site the key reads. A slug that works with a key can answer 404 with a different key.
Article fields
| Field | Type | Notes |
|---|---|---|
| id | string | Stable for the life of the article. |
| slug | string | For this site. |
| title | string | |
| excerpt | string or null | |
| bodyHtml | string or null | Cleaned HTML. Safe to render. |
| coverImage | object or null | |
| tags | array of strings | Empty when there are none. |
| authorName | string or null | |
| publishedAt | ISO 8601 or null | When it went live on this site. |
| updatedAt | ISO 8601 or null | Last change of any kind. |
Paging
Paging uses a cursor. Pass nextCursor back as cursor.
let cursor = null do { const page = await copper.listPosts({ cursor }) for (const post of page.data) handle(post) cursor = page.nextCursor } while (cursor)
The SDK has allPosts. It walks every page.
What is returned
Only published articles are returned. Only articles on the site the key reads. Deleted articles are never returned.
A deleted article stops appearing. It does not come back as an empty record. Use the post.unpublished webhook to see a removal.
Caching
cache-control: private, max-age=60, stale-while-revalidate=3600 vary: Authorization
| Fresh for | 60 seconds |
|---|---|
| Served stale for | 1 hour while revalidating |
A published article can take up to the fresh window to appear.
The response is private. It depends entirely on the key. A shared cache keyed on the url alone would hand articles between accounts.
Over the read allowance
Reads past the plan allowance are still served. The response carries a header.
copper-usage: reads-over-limit
See Plans and limits.
