Inbound webhooks & HTTP receivers

← Home

These are the incoming doors into PressOS: places other systems (Twilio, MockupDesk, cron jobs, etc.) can send data. The address is the path after your site URL (if the app lives under a prefix like /pressos, put that in front of each path).

Live feed (unified webhook)

Tool-originated events (MockupDesk, PrintPath, SeparationsAI, etc.) POST JSON to one endpoint. COGS / invoicing canonical types include: cogs.blank_matched, payment.stripe_fee_matched, shipping.cost_matched, invoice.print_matched, invoice.paid (see EventType enum on this page).

Webhook address How it’s called Security What it does
/webhooks/events POST
Callers must send a shared secret in the request (like a password only your tools know). It has to match the webhook secret configured for this PressOS server.
Technical details Header X-Webhook-Secret must match WEBHOOK_SECRET, PRESSOS_WEBHOOK_SECRET, or PRINTBRAIN_WEBHOOK_SECRET.
Receives events from your tools, saves them to the activity log, and runs follow-up rules.
/webhooks/ping GET, POST
No secret required—this is only a quick “is the server reachable?” check.
Technical details None (reachability check).
Returns a small JSON response with hints for configuring the main webhook URL.
/webhooks/twilio/voicemail-transcription POST
Twilio proves each request is really from Twilio (not someone faking a callback). Your Twilio auth token on the server is used to verify that proof.
Technical details Twilio: X-Twilio-Signature validated with TWILIO_AUTH_TOKEN (twilio.request_validator). Optional TWILIO_WEBHOOK_PUBLIC_BASE_URL if proxy headers are wrong.
When Twilio finishes transcribing a voicemail, it posts the text here for the activity log.
/webhooks/twilio/voice/voicemail-transcription POST
Same security as the shorter voicemail URL above—Twilio-signed requests only.
Technical details Same as /webhooks/twilio/voicemail-transcription.
Same as /webhooks/twilio/voicemail-transcription; alternate path your Twilio app may use.
/webhooks/twilio/sms/inbound POST
Twilio signs the request so only real Twilio traffic can post customer SMS here.
Technical details Twilio signature (TWILIO_AUTH_TOKEN).
Incoming SMS: saves the message, conversation, and reply draft queue; logs the event.
/webhooks/twilio/sms/status POST
Twilio signs the request so delivery status updates can’t be forged.
Technical details Twilio signature (TWILIO_AUTH_TOKEN).
Delivery receipts (sent, delivered, failed, etc.) for outbound SMS.

Integrations (HMAC + idempotency)

Server-to-server POSTs that require Idempotency-Key and (when secrets are set) HMAC signatures.

Webhook address How it’s called Security What it does
/api/inbox/insights POST
If webhook signing is turned on, the sender must include a cryptographic signature. Every request also needs a one-time id key so the same payload isn’t processed twice.
Technical details If PRINTBRAIN_WEBHOOK_SECRET is set: X-PrintBrain-Signature or X-Signature (sha256=…). Idempotency-Key required.
Approved insights from other systems land in the inbox (and optionally link to a graph node).
/api/pricing/quote POST
If pricing signing is turned on, the caller must prove the request with a signature matching your PressOS pricing secret. Includes a one-time id key per request.
Technical details If PRESSOS_PRICING_HMAC_SECRET is set: X-PressOS-Signature / X-PrintBrain-Signature / X-Signature. Idempotency-Key required.
Pricing quote requests (e.g. from MockupDesk); stores a snapshot for reference.

Scheduled / automation (HTTP triggers)

Typically called by cron on the app host. No app-level API key unless noted—restrict by network or reverse proxy in production.

Webhook address How it’s called Security What it does
/api/roadmap/ingest POST
This URL does not ask for a password inside the app. Only trusted machines on your network (or localhost) should be able to reach it.
Technical details None in app (protect via network / cron only).
Bulk-imports workspace roadmaps into snapshots (PressOS Progress / roadmap sync).
/api/gmail/ingest POST
No extra header password—Gmail access uses OAuth tokens stored on the server, not in each request.
Technical details None in app (Gmail OAuth uses service account / token on server).
Pulls Gmail threads that are labeled for creating work orders.
/api/gmail/ingest-print-invoices POST
If you configured an invoice API key, callers must send that key in a header. Otherwise treat this URL as private (same as other cron-style triggers).
Technical details If INVOICE_WORKFLOW_API_KEY is set: header X-PressOS-Key must match.
Emails with the Print Invoice label: PDF to storage, database row, label update.
/api/gmail/ingest-print-confirmations POST
Same API key as invoice/cron as configured in PressOS. Gmail must have labels **Print Confirmation** and **Print Confirmation Complete** (names configurable in PressOS via env).
Technical details If INVOICE_WORKFLOW_API_KEY is set: header X-PressOS-Key must match.
Proof-approval emails: subject **Proof approval needed** + work order name, ≥2 PDFs → S3 **PrintPartnerConfirmations/**, Postgres row; queue label kept until ack (Photo/parens variants accepted).
/api/print-confirmation-pdf-uploads GET
PrintPath (or manual script) poll for pending handoffs; presigned S3 GET URLs in JSON.
Technical details If INVOICE_WORKFLOW_API_KEY is set: header X-PressOS-Key must match.
List pending print-confirmation rows (not yet acked). Query: days, limit.
/api/print-confirmation-pdf-uploads/ack POST
PrintPath calls after import; moves Gmail to **Print Confirmation Complete**.
Technical details If INVOICE_WORKFLOW_API_KEY is set: header X-PressOS-Key must match.
Idempotent ack by gmail_thread_id; optional pressos_row_id and printpath_confirmation_id in JSON body.
/api/gmail/inbox-stale-check POST
No in-app password—meant to be triggered by a scheduled job on a trusted server only.
Technical details None in app (cron).
Counts stale inbox messages and may send a reminder push notification.

Canonical event_type strings

For POST /webhooks/events, payloads use event_type from src/live_feed/event_types.py. Legacy snake_case aliases may still appear from older tools.

Show all 57 values
cogs.blank_matched invoice.paid invoice.print_matched lead.disqualified lead.followup_needed lead.new_inquiry lead.qualified lead.response_drafted lead.response_sent mockup.approved mockup.created mockup.regression_failed mockup.rejected mockup.revision_requested mockup_approved mockup_created mockup_rejected pantone.confidence.low payment.invoice_sent payment.overdue payment.received payment.stripe_fee_matched print_confirmation.ready printpath.cogs.incomplete production.complete production.qc_check production.qc_failed production.qc_passed production.started production_complete production_started quote.accepted quote.expired quote.generated quote.sent separations.artwork_missing separations.complete separations.failed separations.started separations_created shipping.cost_matched shipping.delivered shipping.exception shipping.in_transit shipping.label_created shipping.picked_up twilio.sms.inbound twilio.sms.outbound twilio.sms.status voicemail.transcribed work_order.approved work_order.changes_requested work_order.created work_order.partner_confirmed work_order.rejected work_order.routed_to_partner work_order_created

Heads-up: If a row says there’s no password checked inside the app, treat that URL as private—only your own server or VPN should reach it unless you add extra protection (firewall, secret, etc.).