---
title: "Content API and receiver reference"
description: "Read approved content from your server and implement durable, signed publication delivery."
updated: "2026-09-11"
verifiedAgainst:
  - apps/web/app/api/integrations/content/route.ts
  - apps/web/lib/server/publishing-integrations-content-api.ts
  - apps/web/lib/server/publishing-integrations-api-keys.ts
  - apps/web/components/publishing-integration-developer-tools.tsx
  - integrations/nextjs/README.md
  - workers/publishing-integrations-adapters.ts
---

The Content API complements a connected destination. Reading a release does not
confirm publication. Your receiver still implements the signed publication and
withdrawal contract so Blogged can verify delivery and expose summary links.

## Create a key

Open **Integrations → Developer API**. An owner or admin creates a key with
**Read approved content** access and selects its destination. Copy the key when
shown and keep it on your server. A separate **Send server analytics** key is for
[conversion events](/integrations/analytics), not content reads.

Keys expire after 90 days, are shown once, and can be revoked from the same
section. A Project can have ten active keys. Each key permits 300 requests per
minute; honor HTTP 429 and `Retry-After`.

## Read approved releases

```sh
curl 'https://app.blogged.dev/api/integrations/content?limit=10'   -H 'Authorization: Bearer YOUR_SERVER_SIDE_KEY'
```

The list returns releases for that key's destination. Follow `nextCursor` until
`hasMore` is false, then retain that cursor for polling. Pages contain at most
20 articles. The polling window overlaps by five seconds: deduplicate by
publication ID, revision, state and delivery state.

| Endpoint or result                      | Handling                                                                         |
| --------------------------------------- | -------------------------------------------------------------------------------- |
| `GET /api/integrations/content`         | Read destination-scoped approved releases, including summary-only projections    |
| `GET /api/integrations/content/POST_ID` | Read one approved release                                                        |
| HTTP 410 for a withdrawn article        | Process the withdrawal tombstone; stop serving that managed copy                 |
| HTTP 409 for a waiting summary          | Wait for the verified primary article and retry later                            |
| Authenticated asset `downloadUrl`       | Copy bytes from your server into your own durable storage and rewrite image URLs |

Do not expose keys in browser JavaScript, page HTML or image URLs. They are
server credentials. Keep your Project's source blog domain valid so relative
article links and managed image references can be resolved.

## Receive signed operations

The [Next.js receiver ZIP](https://app.blogged.dev/integrations/blogged-nextjs-receiver.zip)
contains the implementation, deployment instructions and receiver tests.
For another application, use the same versioned contract in the
[setup reference](https://app.blogged.dev/integrations/guide).

Validate `X-Blogged-Timestamp` and `X-Blogged-Signature` using HMAC-SHA256 over
`timestamp + "." + rawBody` and your shared signing secret. Reject stale timestamps
outside the five-minute window before processing the payload.

| Operation          | Purpose                                            |
| ------------------ | -------------------------------------------------- |
| `connection.test`  | Verify receiver capabilities                       |
| `article.publish`  | Create or reconcile the managed publication        |
| `article.inspect`  | Read its remote revision and content               |
| `article.update`   | Apply an explicitly reviewed version conditionally |
| `article.withdraw` | Remove the managed article from public service     |

Preserve delivery IDs, durable publication IDs and revisions. Replayed requests
must not duplicate articles or overwrite a later version. An accepted response
means work is pending: send a signed completion receipt to
`https://app.blogged.dev/api/integrations/receipts`, or return the completed receipt
on redelivery. Copy all granted images before reporting completion. Temporary
image grants expire; do not hotlink them as permanent reader images.

Verify one publish, replay, update and withdrawal with disposable content before
using a new receiver. Check both its durable records and public page; a successful
HTTP response alone does not establish a published article.
