Platform · API & webhooks

Everything the console does, the API does.

Available on Hosted Pro and to partners. REST over HTTPS, JSON, OAuth 2.0 client credentials or scoped API keys, webhooks with signed payloads. Designed so an IT provider can automate onboarding and a compliance platform can pull evidence. Reference outline — endpoints finalize at general availability

Base URL and versioning

https://api.pxcmail.com/v1/

Versions are in the path. Breaking changes ship as a new version with at least 12 months of overlap; additive changes (new fields) are not breaking. Every response carries X-PXC-Version and X-Request-Id.

Authentication

  • API keys: created in Console → Security → API keys with scopes (read:audit, read:archive, write:users, write:policy, write:holds, read:reports, partner:*); shown once; rotatable; IP allowlist optional. Sent as Authorization: Bearer <key>.
  • OAuth 2.0 client credentials for partner integrations acting across client organizations; tokens valid 60 minutes; organization selected with X-PXC-Org.
  • All calls TLS 1.2+; keys never grant message-content access unless the read:archive scope is granted by an Owner with dual approval; such access is logged like console access.

Resources

ResourceEndpointsNotes
OrganizationsGET /organizations/{id} · PATCH (name, profile, security officer) · partners: GET /organizations, POST (provision)Provisioning returns agreement links to sign; status moves pending_agreement → pending_dns → active
DomainsGET/POST /organizations/{id}/domains · GET /domains/{id}/dns (records + live check) · POST /domains/{id}/verifyReturns SPF, DKIM CNAMEs, MAIL FROM, MX, DMARC suggestions
ConnectionsGET/POST /organizations/{id}/connections (google_relay, m365_connector, mx) · POST /connections/{id}/rotate-credentialCredential returned once
UsersGET/POST/PATCH/DELETE /organizations/{id}/users · POST /users/{id}/mfa/reset · POST /users/{id}/app-passwords · GET /users/{id}/devices · POST /devices/{id}/wipeSeats counted from active users; directory sync marks source
PoliciesGET /organizations/{id}/policy · PUT (full document, versioned) · POST /policy/test (sample message → actions) · GET /policy/versions · POST /policy/rollbackPolicy document schema published as JSON Schema
Messages (metadata)GET /organizations/{id}/messages?from=&to=&sender=&recipient=&action=&finding= · GET /messages/{id} · POST /messages/{id}/revoke · POST /messages/{id}/resend-notificationContent never returned here
Holds (quarantine)GET /organizations/{id}/holds · POST /holds/{id}/release · POST /holds/{id}/rejectReason required; logged
ArchivePOST /organizations/{id}/archive/search · GET /archive/messages/{id} (scope read:archive) · POST /archive/exports · GET /archive/exports/{id} (status, download URL, manifest)Exports asynchronous; signed URLs valid 24 h
Legal holdsGET/POST /organizations/{id}/legal-holds · POST /legal-holds/{id}/releaseCustodian, matter query, date range
Audit logGET /organizations/{id}/audit?from=&to=&actor=&action=Cursor pagination; up to 6 years
ReportsGET /organizations/{id}/reports/compliance?period= · GET /reports/dmarc · GET /reports/deliverability · POST /reports/evidence-pack (regulator type)PDF and JSON
BillingGET /organizations/{id}/subscription · PATCH (seats, add-ons) · GET /invoicesPartners: bill-through statements
StatusGET /statusPublic; no auth

Webhooks

Register endpoints in Console → Security → Webhooks or via POST /organizations/{id}/webhooks. Payloads are JSON, signed with HMAC-SHA256 in X-PXC-Signature (timestamped; replay window 5 minutes), retried with exponential backoff for 24 hours.

EventWhen
message.scannedPolicy decision made (metadata, findings, action)
message.delivered / message.locked / message.opened / message.bouncedDelivery lifecycle
message.held / hold.released / hold.rejectedQuarantine
policy.updatedWith version and actor
user.created / user.removed / user.mfa_reset / device.wipedIdentity and devices
dns.changed / connection.failed / reputation.warning / reputation.pausedHealth
legal_hold.created / legal_hold.released / export.completedArchive
agreement.signed / subscription.updated / invoice.paid / invoice.failedAccount

Rate limits and pagination

600 requests per minute per key (burst 100); archive search 60 per minute; exports 10 concurrent. Responses include X-RateLimit-Remaining. Lists use cursor pagination (?cursor=&limit=, max 200).

Errors

Standard HTTP codes with a JSON body: {"error":{"code":"policy.invalid","message":"…","field":"rules[3].action","request_id":"…"}}. Codes are stable and documented.

Data handling

API traffic is logged like console traffic. Message content is only available through read:archive on Hosted Pro with dual approval, and such reads appear in the organization’s access log. Webhook payloads never contain content.

SDKs and tools

OpenAPI 3.1 specification published at GA; TypeScript and Python SDKs; a Terraform provider for partners who provision many organizations; Postman collection.

Example — provision a client (partner)

POST /v1/organizations
{ "name": "Lakeside Family Dental", "profile": "hipaa", "plan": "gateway",
  "domains": ["lakesidedental.com"], "owner_email": "[email protected]",
  "security_officer": {"name": "Jordan Reyes", "email": "[email protected]"} }

201 Created
{ "id": "org_7f3a…", "status": "pending_agreement",
  "agreements": [{"type": "baa", "sign_url": "https://sign.pxcmail.com/…"}],
  "next": "Sign the BAA, then GET /domains/{id}/dns for records." }

Building on PXCMail?

Partners get API access, a sandbox organization and an engineer to talk to.

Partner program