For developers

Build on TraXmark: one REST surface, API keys with explicit scopes, RFC 7807 errors and cursor pagination.

OpenAPI 3.1.0 reference

TraXmark API v1

Email engagement intelligence over one REST surface. Read and write contacts, messages, events, documents, envelopes and proposals with the same key format, error shape and pagination contract.

  • Authentication: a trax_… API key. Only its Argon2id hash is stored.
  • Errors follow RFC 7807 and carry an i18n key plus the x-correlation-id header.
  • Cursor pagination on every list, capped at 100 items per page.
  • Anti-enumeration: a resource that does not exist and one you cannot access both answer 404.

Resources

Six resources, each readable and writable through matching scopes.

  • /api/v1/contactsRead with scope contacts:read, write with scope contacts:write.
  • /api/v1/messagesRead with scope messages:read, write with scope messages:write.
  • /api/v1/eventsRead with scope events:read, write with scope events:write.
  • /api/v1/documentsRead with scope documents:read, write with scope documents:write.
  • /api/v1/envelopesRead with scope envelopes:read, write with scope envelopes:write.
  • /api/v1/proposalsRead with scope proposals:read, write with scope proposals:write.

Scopes

Every API key is issued with an explicit set of 16 scopes.

  • campaigns:read
  • campaigns:write
  • contacts:read
  • contacts:write
  • messages:read
  • messages:write
  • events:read
  • events:write
  • documents:read
  • documents:write
  • envelopes:read
  • envelopes:write
  • proposals:read
  • proposals:write
  • devices:read
  • devices:write

A request without the required scope is rejected with 403.

Endpoints (19)

All routes live under one base URL and answer with the same error shape.

MethodEndpointScopeDescription
GET/api/v1/contactscontacts:readReturns a page of contacts (cursor pagination, cap 100).
POST/api/v1/contactscontacts:writeCreates a new contacts entry.
GET/api/v1/contacts/{id}contacts:readFetches a single contacts item by ID. Missing or denied access both return 404.
GET/api/v1/messagesmessages:readReturns a page of messages (cursor pagination, cap 100).
POST/api/v1/messagesmessages:writeCreates a new messages entry.
GET/api/v1/messages/{id}messages:readFetches a single messages item by ID. Missing or denied access both return 404.
GET/api/v1/eventsevents:readReturns a page of events (cursor pagination, cap 100).
POST/api/v1/eventsevents:writeCreates a new events entry.
GET/api/v1/events/{id}events:readFetches a single events item by ID. Missing or denied access both return 404.
GET/api/v1/documentsdocuments:readReturns a page of documents (cursor pagination, cap 100).
POST/api/v1/documentsdocuments:writeCreates a new documents entry.
GET/api/v1/documents/{id}documents:readFetches a single documents item by ID. Missing or denied access both return 404.
GET/api/v1/envelopesenvelopes:readReturns a page of envelopes (cursor pagination, cap 100).
POST/api/v1/envelopesenvelopes:writeCreates a new envelopes entry.
GET/api/v1/envelopes/{id}envelopes:readFetches a single envelopes item by ID. Missing or denied access both return 404.
GET/api/v1/proposalsproposals:readReturns a page of proposals (cursor pagination, cap 100).
POST/api/v1/proposalsproposals:writeCreates a new proposals entry.
GET/api/v1/proposals/{id}proposals:readFetches a single proposals item by ID. Missing or denied access both return 404.
POST/api/v1/campaigns/sendcampaigns:writeStarts a campaign. Consumes one unit of campaigns_per_month plus messages_per_month equal to the number of recipients. Over the message limit the API answers 403 — unless the tenant has overage (platform_config → overage.enabled) and a Stripe customer; then a block of 1000 messages is invoiced, the limit grows and the send goes through.

SDK snippets

Copy-paste starting points against the public base URL.

Node.js

Native fetch, RFC 7807 body on failure, cursor from nextCursor.

const res = await fetch('https://api.traxmark.com/api/v1/contacts?limit=50', {
  headers: { Authorization: `Bearer ${process.env.TRAXMARK_API_KEY}` },
});
if (!res.ok) throw new Error(await res.text()); // RFC7807 JSON
const { items, nextCursor } = await res.json();

Python

requests with raise_for_status and JSON decoding.

import requests
r = requests.get('https://api.traxmark.com/api/v1/contacts',
                 headers={'Authorization': f'Bearer {API_KEY}'}, params={'limit': 50})
r.raise_for_status(); data = r.json()

Replace the environment variable with a key issued in Settings → API keys; it starts with trax_.