TMJ Journey docs  /  Developer reference

Publisher API

Read what your program published and how many practices took it up. Two endpoints, read-only, bearer token.

This API is for publisher programs — organisations that author content (form templates, treatment plans, code libraries, SmartPhrases, intake forms) and offer it to practices running TMJ Journey. If you are a practice rather than a publisher, this is not the API you want; see the docs index.

Base URL

Publisher data is program-level rather than practice-level, so it is served from the platform host, not a practice domain.

https://tmjjourney.com

Authentication

A token is generated inside TMJ Journey at Publisher → Account → API tokens. It looks like pub_ followed by 40 hex characters, and it is shown once, at generation — we store only a SHA-256 hash of it, so a lost token cannot be recovered and has to be replaced.

Authorization: Bearer pub_0123456789abcdef0123456789abcdef01234567

The token identifies your program. Every response is scoped to it — there is no parameter for requesting another program's data, and no way to widen the scope of a token after it is issued.

This is a server-side credential. Unlike the publishable key used by the Lead Intake API, a pub_ token is not origin-restricted and must never appear in page source, a front-end bundle, or a repository. Revoke it in the same screen that issued it if it leaks.

Rate limits

60 requests per 60 seconds, counted per token. Every response carries the current state:

HeaderMeaning
X-RateLimit-LimitAlways 60.
X-RateLimit-RemainingRequests left in the current window.
X-RateLimit-ResetUnix seconds at which the window resets.
Retry-AfterSeconds to wait. Sent only with a 429.

GET /api/public/publisher/activity

The most recent publishing actions taken inside your program — what was created, updated or published, by whom, and when.

Query parameters

NameTypeDefaultNotes
limitinteger50Clamped to 1100. Out-of-range and non-numeric values are clamped rather than rejected.
curl https://tmjjourney.com/api/public/publisher/activity?limit=25 \
  -H "Authorization: Bearer pub_<your-token>"

Response

{
  "program": "TMJ_INTERNATIONAL",
  "activity": [
    {
      "id":            "clx9f2k0a0001qw...",
      "action":        "PUBLISHED",
      "resourceType":  "MasterFormTemplate",
      "resourceId":    "clx8b1h9z0004rt...",
      "resourceLabel": "TMJ Initial Consultation",
      "userEmail":     "heather@example.org",
      "metadata":      { "version": 3 },
      "createdAt":     "2026-09-02T17:41:08.221Z"
    }
  ]
}

Ordered newest first. metadata is free-form JSON that varies by action and may be null — treat it as advisory and do not key logic off its shape.

GET /api/public/publisher/adoption

How practices have responded to what you offered them. Each content type is counted by decision, so you can see what has been taken up and what is still sitting in an inbox.

curl https://tmjjourney.com/api/public/publisher/adoption \
  -H "Authorization: Bearer pub_<your-token>"

Response

{
  "program": "TMJ_INTERNATIONAL",
  "adoption": {
    "MasterFormTemplate":          { "pending": 4, "accepted": 22, "rejected": 1, "total": 27 },
    "MasterCodeLibraryBundle":     { "pending": 0, "accepted": 6,  "rejected": 0, "total": 6  },
    "MasterTreatmentPlanTemplate": { "pending": 2, "accepted": 11, "rejected": 0, "total": 13 },
    "MasterSmartPhrase":           { "pending": 0, "accepted": 34, "rejected": 2, "total": 36 },
    "MasterIntakeForm":            { "pending": 5, "accepted": 18, "rejected": 0, "total": 23 },
    "OlmosLibraryDocument":        { "pending": 0, "accepted": 0,  "rejected": 0, "total": 0  }
  }
}

Reading the numbers

  • All six keys are always present, even when a program publishes nothing of that type. Zeros are real answers, not missing data.
  • total is the sum of the three decisions — it is the number of offers made, not the number of practices.
  • OlmosLibraryDocument is only ever non-zero for programs that publish that library; for everyone else it is structurally zero.
  • A program that publishes training content only will report zeros throughout, because training is read in place rather than adopted — there is no offer to accept.

Errors

StatusMeaning
401Missing, malformed, revoked or unknown token — also returned when the token's program has been deactivated. Deliberately not distinguished.
429Rate limit exceeded. Wait Retry-After seconds.

Errors are JSON: { "error": "Unauthorized" }.

What this API does and does not do

  • Read-only. There is no write endpoint. Authoring and publishing happen in the app.
  • No patient data, ever. These endpoints return publishing metadata and counts. No PHI passes through them, which is why a program-level token is sufficient.
  • Scoped to one program. A token cannot read across programs.
  • Last use is stamped on the token so an unused or unexpected one is visible in the issuing screen.

Questions, or need something this does not cover? Get in touch — it reaches the people who wrote it.