Concepts

The four core concepts of the PrivacyFlow API — appId, contactId, credential scoping, and the poll-only delivery model with destructive reads.

PrivacyFlow exposes a small surface area on purpose. This page covers the four ideas that determine how you architect your client: the appId, the contactId, the credential type, and the poll-only, destructive-read delivery model.

The appId

An appId is a single connected messenger account — one Signal number, one SimpleX profile, or one Session ID. A customer can only talk to one app at a time; the app is the identity they reach.

A single PrivacyFlow account can hold many apps. Each credential (API key) the dashboard issues is scoped to one or more appIds via the appIds[] field on the key. When you poll, the API round-robins across every appId your key covers — you don’t choose which queue to read from. When you send, the appId in each message must be in your key’s appIds[] or the message is rejected per-message.

Tip

Most automation use cases want one appId per credential. Use separate keys per project so a compromised key only leaks one app’s traffic. The dashboard issues as many credentials as you need.

The contactId

The contactId is how the recipient is addressed on the destination messenger. Its format depends on messenger — see contact formats on the send page. The API validates only that the field is non-empty; the actual format check happens downstream by the messenger, so an invalid contactId produces a per-message failure in the send response rather than a 400 from the API.

Poll-only delivery

Inbound messages land in a Redis list keyed poll:{appId} and you read them via GET /api/v1/messages/poll. Delivery is poll-only with destructive reads.

The trade-off is yours to manage:

  • Poll interval. The MCP server and Agent Zero channel both default to a ~3-second poll loop. Pick an interval that balances latency against your rate budget (poll is capped at 100 requests per minute per credential — see rate limiting).
  • Destructive reads. Polling removes a message from the queue. Persist or process the message before the next poll; a crashed client cannot re-read it.
  • No ordering guarantees across polls. Each poll returns whatever was first-in on each queue, but across your appIds there’s no global order.

Warning

The messenger field on a polled message tells you which network it came in on. It must be passed back unchanged on send when you reply — replying to a SimpleX contact via messenger: "signal" will fail.

Group messages

A polled message carries isGroupMessage and an optional groupId. If isGroupMessage is true, groupId is set and you should include it on the reply to land back in the same group thread. If false, omit groupId entirely — sending a groupId for a direct message is undefined.

Credential types

The dashboard issues three credential types. They all authenticate to the same API surface — the only thing that differs is which HTTP header you’re allowed to use.

Credential typeAllowed header(s)Use case
api-keyAuthorization: Bearer <key> or X-API-Key: <key>Standard API key for automation. The default.
webhook-bearerAuthorization: Bearer <key> onlyToken-based webhook auth, when your webhook receiver already speaks Bearer.
webhook-headerX-Webhook-Token: <key> onlyCustom-header webhook auth, when your receiver prefers a dedicated header.

See Authentication for the full header matrix and how to choose.

Rate-limit keys and credentialId

Every credential carries a stable credentialId. Rate limits are bucketed on the credentialId, not the key string, so rotating a key keeps your rate budget — you don’t get a fresh limit by rotating. See rate limiting for the per-credential caps and the multi-process caveat.

API scope

The public API is a message relay: poll inbound, send outbound. Contact lists, group membership, read receipts, presence, media, app settings, billing, webhook configuration, and outbound delivery status are managed via the dashboard or are not exposed.

A 202 on send means “accepted into queue”, not “delivered to recipient”. Group creation, credential issuance, and account settings happen in the dashboard; the API moves messages between you and your customers.

Last updated: