Skip to main content
This is the REST API the BounceBox Zapier integration calls. It is documented for reviewers verifying the integration and for integrators building against the same surface. Base URL: https://bouncebox.app

Authentication

BounceBox uses OAuth 2.0 authorization-code flow — no PKCE, no scopes. All API calls send Authorization: Bearer <access_token>. Only token hashes are stored server-side.

Authorize

GET /api/integrations/zapier/oauth/authorize Query parameters: client_id, redirect_uri, response_type=code, state. Redirects to the dashboard login, then 302s back to redirect_uri with a code (10-minute TTL) and state.

Token

POST /api/integrations/zapier/oauth/token JSON or form-encoded body: grant_type=authorization_code, code, redirect_uri, client_id, client_secret. Response:

Refresh

POST /api/integrations/zapier/oauth/refresh Body: grant_type=refresh_token, refresh_token, client_id, client_secret. Same response shape as the token endpoint. Rotates both tokens — the old pair stops working.

Revoke

POST /api/integrations/zapier/oauth/revoke Client-authenticated. Revokes the token row. An invalid or expired bearer token returns 401 with {"error": "invalid_token"}.

Endpoints

All endpoints are scoped to the workspace the token was issued for.

Connection test

GET /api/integrations/zapier/me

List mailboxes

GET /api/integrations/zapier/mailboxes
Source for the mailbox dropdown in Zap steps.

Received mail samples

GET /api/integrations/zapier/triggers/received?mailbox_id&limit limit accepts 1–10. Returns { "emails": [...] } — the newest received emails, each in the mail.received payload shape below. Returns 404 when mailbox_id belongs to another workspace.

Processed mail samples

GET /api/integrations/zapier/triggers/processed?mailbox_id&limit Returns { "emails": [...] } — newest emails joined to their latest extraction result, each in the mail.processed payload shape below.

Send email

POST /api/integrations/zapier/emails Body:
Provide text or html or at least one attachment. Returns 202 with { "email_id", "mailbox_id", "status": "processing" } — the email enters the normal pipeline. Errors: 400 missing mailbox_id or empty content, 404 foreign mailbox.

Email actions

POST /api/integrations/zapier/actions/emails/{id} Body: { "action": "approve" | "reprocess" | "skip", "result_id": "optional", "expected_revision": "optional" }. Returns { "ok": true, "emailId": "...", "action": "...", ... } — approve adds resultId and revision. Errors: 400 unknown action, 404 email or result not found, 409 conflict (for example a stale revision), 503 scheduling failed.

Subscribe to webhooks

POST /api/integrations/zapier/webhooks/subscribe Body: { "webhook_url": "required", "event_type": "mail.received | mail.processed", "mailbox_id": "optional" }. webhook_url must be a public HTTPS URL — the same rule as mailbox webhooks. Plain HTTP, localhost, and private network addresses are rejected with 400. Returns 201 with { "subscription_id": "..." }. Re-subscribing an identical subscription returns 200 — the call is idempotent on workspace + event + URL + mailbox.

Unsubscribe

DELETE /api/integrations/zapier/webhooks/{id} Returns 204 always — idempotent.

Webhook deliveries

Deliveries POST a JSON payload to the subscribed URL with an X-BounceBox-Signature header. A subscription auto-deactivates after consecutive delivery failures. mail.received fires at intake. mail.processed fires when extraction finishes. Payload fields:
  • Zapier integration — connect your account, triggers, and actions from the user side.
  • Webhooks — per-mailbox webhook output without Zapier.