Skip to the page
Orbit

Run it

Signals and customer mail

On this page

Source settings live at /app/sources. rer setup generates the source encryption key in private local settings; rer deploy generates it only when the target has no key and inherits an existing key. Neither command prints it. Source signing secrets are encrypted with AES-GCM; the source list never returns them. Connecting a source generates its signing secret and shows it once with Copy. Reloading and source lists never reveal it. Advanced contains signing-secret rotation, which takes effect immediately; update your connected tools before delivering more events.

POST an event to /api/v1/signals/<source-id>. Set X-Orbit-Timestamp to the current Unix time in seconds. X-Orbit-Signature is the hexadecimal HMAC-SHA256 of <timestamp>.<exact request body> using that source’s secret. The timestamp must be within five minutes of the deployment clock. The body limit is 262144 bytes.

An event carries eventId, type, subject, and ISO occurredAt. It can include record: {type: "contact"|"company"|"opportunity", id}, email, domain, identityBasis, permanentBounce, and data. Explicit IDs take precedence over exact normalized keys and retired aliases. Unknown matches remain in unlinked review. Page views, chats and downloads require the identity basis the source already holds; operator review cannot bypass that requirement. Standard types are declared in ingestion/contracts.ts; source-specific types use <source-id>:<type>.

Delivery events go to /api/v1/mail/events/sendgrid. Configure the SendGrid signed Event Webhook and put its public key in SENDGRID_WEBHOOK_PUBLIC_KEY. Replies go to /api/v1/mail/events/reply; configure a signed SendGrid Inbound Parse security policy and put its public key in SENDGRID_PARSE_PUBLIC_KEY. Verification uses ECDSA P-256 over the untouched timestamp and raw body, including multipart bytes. The event timestamp has a five-minute tolerance. Events carrying unknown delivery correlation IDs write nothing to this deployment.

Set MAIL_REPLY_TO to the configured Inbound Parse address. Set SENDGRID_UNSUBSCRIBE_GROUP_ID to the dedicated SendGrid unsubscribe group. SendGrid ASM inserts the provider-handled unsubscribe headers and footer. Global subscription tracking is explicitly disabled; click/open tracking remains disabled. Native SMTP acceptance testing confirmed group-only suppression and both one-click headers with this configuration. Every customer message carries Message-ID, References when applicable, List-Unsubscribe, and List-Unsubscribe-Post headers. Replies with a recognized reference are linked without using subject similarity. Replies with no unique thread remain in /api/v1/sources/replies for operator review.

The SendGrid API key needs Mail Send and Email Activity read access. Reconciliation queries the custom delivery argument through /v3/messages; a missing permission remains a visible provider lookup error. It never resends an unresolved submission. The deployment timer runs each minute to dispatch approved schedules, process due queues, and query unresolved submissions at five-minute intervals for up to 24 hours.

Manual sends outside the recipient’s 08:00–18:00 weekday window require the exact local-time confirmation from the approval preview. Schedules move to the next permitted minute and recheck current draft, recipient, association, contactability, operator, and sending limits before dispatch. Limit-blocked approval retains the reviewed message, visible reason and retry time; an operator must explicitly retry. A new customer reply cannot be overwritten by an older accepted receipt.

Provider references: signed Event Webhooks, signed Inbound Parse, Email Activity query syntax.

An optional shared SendGrid relay posts to /api/v1/mail/events/relay. Configure RER_MAIL_RELAY_SECRET with the destination secret. The canonical Base receiver checks x-rer-mail-timestamp and x-rer-mail-signature (v1=<hex HMAC-SHA256>) over <timestamp>.<exact JSON body> with a five-minute tolerance. Customer sends carry rer_product=orbit; other products’ events are ignored. The relay can retry partial failures because destination event IDs are deduplicated. Native SendGrid and signed Parse endpoints remain independently supported.

Mail and calendar capture

/app/capture takes .eml files, an mbox or .ics files from the owner’s own mailbox and calendar exports. Only items with a participant who is a known contact (exact email) or at a known company (exact domain) are stored; the result says how many were not stored and why. A reply to an Orbit send attaches to its thread, a delivery report for an Orbit send records the bounce, and a reply or booked meeting stops that person’s scheduled sends at once. Every other change is a proposal with its evidence that a person accepts, edits or declines. Capture never drafts or sends, and never makes a contact contactable. CONTRACT.md CAPTURE-001 to CAPTURE-007 define it.

On-screen recipes

Website forms use Orbit’s existing fixed publication workflow: save text, compile, review, approve and publish the exact artifact. Sources embeds that actual public form. An exact matching contact email records form.submitted against its linked opportunities. Public form pages allow embedding only from this installation and HTTPS website origins explicitly saved in Settings; private operator pages still refuse framing.

The booking recipe verifies Cal.com’s bare hexadecimal X-Cal-Signature-256 HMAC over the raw body, or Calendly’s Calendly-Webhook-Signature (t=...,v1=...) over timestamp, a period, and the raw body. Calendly signatures have a 180-second tolerance. Cal.com has no signed timestamp header, so Orbit applies a five-minute freshness policy to the signed envelope’s createdAt. Standard created/cancelled envelopes become booking/cancellation signals. Stable event identities include the Cal trigger, booking UID and invitee email, or the Calendly event and invitee URI. Repeat booking deliveries return 409 without another signal. Unknown invitees remain unlinked for operator review.

Zapier and Make use authenticated HTTP actions to a supplied owner-controlled Node adapter. The Sources page provides the complete runnable signing implementation with this installation’s fixed endpoint and the maintained event schema. Its separate adapter credential belongs in an API by Zapier Static Headers connection or Make HTTP v4 Credentials. Keep the Orbit signing key solely in the adapter server’s private environment, outside platform Code steps, mappings and history. The copy-paste signing code runs on the owner server; a secure in-platform Code signing step is not claimed. Hosting that adapter over HTTPS and live platform-account delivery remain owner deployment steps.

Send the immutable original serialized event body, including its upstream event ID and occurred time. Missing identity is rejected. The adapter validates and forwards those exact bytes, makes fresh signature headers for each attempt, and returns Orbit’s actual status. Exact Orbit replays return the existing receipt; changed content under the same identity returns a conflict. Network errors report an unknown outcome and require a retry with the same body.

Send test event requires a native full-operator session and same-origin request. The server chooses a new event identity, signs with the source’s encrypted secret and calls the normal signature-verifying ingestion route. The customer is selected explicitly, defaulting to the most recently added contact. Test signals stay visibly labelled in NOW and customer evidence. They do not grant mail approval.

Edit this page on GitHub