TextMaster · AsyncAPI Specification
Textmaster Event Surface
Version
View Spec
View on GitHub
CompanyTranslationLocalizationLanguage ServicesCopywritingProofreadingMachine TranslationContent ProductionTranslation MemoryGlossaryEcommerce LocalizationProduct Information ManagementWebhookAuthenticationSoftware-as-a-ServiceAsyncAPIEvents
AsyncAPI Specification
generated: '2026-08-17'
method: searched
source: >-
https://developer.textmaster.com/webhooks-and-events/events +
https://developer.textmaster.com/webhooks-and-events/webhooks +
https://developer.textmaster.com/webhooks-and-events/webhooks/creating-webhooks +
https://developer.textmaster.com/webhooks-and-events/webhooks/securing-webhooks +
https://developer.textmaster.com/webhooks-and-events/webhooks/troubleshooting-webhooks +
https://developer.textmaster.com/guides/integrator-best-practices +
openapi/textmaster-api-v1-openapi.yml
checked: '2026-08-17'
spec_type: none
summary: >-
TextMaster ships a real, customer-registerable webhook surface — 19 named events across Projects
and Documents, registered through the REST API itself, with a published retry budget, delivery
semantics, an event-type request header and a documented securing pattern. It publishes NO
AsyncAPI document. This artifact is therefore the webhook catalogue, and the apis.yml pointer is
`Webhooks`, not `AsyncAPI`.
asyncapi:
present: false
probed:
- url: https://api.textmaster.com/asyncapi.yaml
status: 404
checked: '2026-08-17'
- url: https://developer.textmaster.com/llms.txt
status: 200
checked: '2026-08-17'
finding: >-
The portal's complete 58-page index contains no AsyncAPI, event-catalog spec, or streaming
page. The event contract is prose + the callback objects inside the OpenAPI.
note: >-
No AsyncAPI is published anywhere. Not fabricated. No `AsyncAPI` pointer is emitted; the
asyncapi scoring family stays out of this provider's denominator on spec-shape checks while the
`Webhooks` signal is genuinely earned.
webhooks:
customer_registerable: true
registration_mechanism: >-
Webhooks are not a separate resource. They are registered as `callback` objects on the REST
write surface, at three levels of scope, each keyed by event name with a `{ "url": "..." }`
value.
registration_levels:
- level: user (global)
operation: PUT /v1/clients/users/{user_id}
scope_required: ['user:manage', 'user:write']
body_path: user.callback.<event>.url
events_available_in_spec: [waiting_assignment, completed]
note: >-
The spec models only two events at user level, but the creating-webhooks tutorial registers
`word_count_finished` here, so the spec's user-level callback map is narrower than the real
surface. Treat the documented event list as authoritative.
example: |
curl "https://api.textmaster.com/v1/clients/users/USER_ID" \
-X PUT \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"user":{"callback":{"word_count_finished":{"url":"https://example.com/payload"}}}}'
- level: project
operation: POST /v1/clients/projects (and PUT /v1/clients/projects/{project_id})
scope_required: ['project:manage', 'project:write']
body_path: project.callback.<event>.url
description_in_spec: List of callbacks to be called upon Project status changes.
- level: document
operation: >-
POST /v1/clients/projects/{project_id}/documents (and the batch create, and
PUT .../documents/{document_id})
scope_required: ['project:manage', 'project:write']
body_path: document.callback.<event>.url
description_in_spec: List of callbacks to be called upon Document status changes.
openapi_webhooks_block: false
openapi_callbacks_keyword: false
openapi_representation_note: >-
The OpenAPI does NOT use the 3.1 top-level `webhooks` object nor operation-level `callbacks`.
The event surface appears only as ordinary request/response schema properties named `callback`,
plus a `CallbackUrl` component ({url, format}). A code generator reading the spec will produce
a settable field, not a subscription API, and will not know the event names are an enum. This
is the single biggest machine-readability gap in TextMaster's contract, and the reason this
catalogue is worth writing down.
delivery:
method: POST
payload_format: JSON
event_type_header: X-TextMaster-Event
event_type_header_quote: >-
"The X-TextMaster-Event request header can be used to know which event has been received so
that processing can be handled appropriately."
ssl_verification: true
ssl_verification_quote: >-
"By default, TextMaster will verify SSL certificates when delivering payloads. Any SSL errors
will be logged in the webhook's response."
receiver_timeout_seconds: 30
retries: 20
retry_strategy: exponential backoff
delivery_guarantee: at-least-once
ordering_guarantee: none
ordering_quote: >-
"We also cannot guarantee the order in which webhooks are delivered. Your server should
handle receiving events out of order."
consumer_idempotency_required: true
consumer_idempotency_quote: >-
"Your server implementation should be idempotent, meaning it should not error out if
receiving the same webhook multiple times."
expected_response_codes: >-
Any prompt 2xx. The docs suggest 201 or 202 to acknowledge a payload that will not be
processed, and reserving 500 for catastrophic failures.
security:
signature_header: false
signature_header_note: >-
There is NO HMAC signature header today. TextMaster says so plainly and states an intent:
"In the future, TextMaster will use your secret token to create a hash signature of each
payload." Until then a receiver cannot cryptographically verify a delivery.
documented_pattern: shared-secret-in-callback-URL
documented_pattern_detail: >-
The integrator embeds a high-entropy token as a query parameter of the callback URL it
registers (e.g. https://example.com/payload?token=<40 hex chars>) and compares it on receipt.
The docs suggest generating it with `ruby -rsecurerandom -e 'puts SecureRandom.hex(20)'` and
recommend a DIFFERENT token per user of the integrator's service.
weakness_note: >-
A URL query parameter is a weaker channel than a signature header: it is logged by proxies
and web servers by default and it authenticates the endpoint, not the payload. Recorded as
published, not endorsed.
source_ip_allowlist:
recommended_by_provider: false
provider_caveat: >-
"Our public IP addresses are subject to changes, we do not encourage using IP addresses to
secure payload delivery."
production:
- 104.155.57.91
- 104.155.91.236
- 35.205.172.93
- 34.140.71.130
sandbox:
- 34.76.154.26
- 34.76.94.225
- 34.76.144.86
- 35.241.160.58
note: >-
Published verbatim in the integrator best-practices guide. Two disjoint egress ranges
confirm the sandbox is genuinely separate infrastructure, not a flag on production.
observability:
delivery_log: true
delivery_log_detail: >-
TextMaster exposes recent deliveries in the application with the full outbound HTTP request
(headers + JSON payload) and the receiver's response (status, headers, body). Failed
deliveries are visible per attempt.
retention: unquantified
event_count: 19
events:
- resource: project
name: project_in_progress
description: >-
Triggered when a project has launched and is made available to be claimed by an author.
reconciliation_note: >-
The recovery primitive for the missing idempotency key: "Launch process can safely be retried
if this event is not received in a reasonable time (more than 30 minutes)."
- resource: project
name: project_finalized
description: >-
Triggered when a project is finalized, meaning that all documents have been attached to it and
translation memory analysis and/or PEMT have been ran successfully.
- resource: project
name: project_not_launched
description: >-
Triggered when a project with the `auto_launch` option cannot be launched, often due to the
client account not having enough credits on its wallet.
commercial_note: The insufficient-funds event. Essential for any agent that launches projects.
- resource: project
name: project_canceled
description: Triggered when a project is canceled.
spelling_note: >-
Both `project_canceled` and `project_cancelled` appear as accepted callback keys in the
OpenAPI request schema. The events documentation uses the single-l `project_canceled`. A
receiver should tolerate both.
- resource: project
name: project_tm_completed
description: >-
Triggered when a project's translation memory analysis has successfully completed and the
project's cost has been updated accordingly.
commercial_note: Cost changes on this event; re-read the project before launching.
- resource: project
name: project_tm_diff_completed
description: >-
Triggered when a project's "Force Exact Matches" analysis has successfully completed and the
project's cost has been updated accordingly.
- resource: project
name: project_in_review
description: >-
Triggered when the work for all project's documents has been submitted, and the documents are
ready for internal quality control or for review by the client.
- resource: document
name: waiting_assignment
kind: status-change
description: Document is published and awaiting an author.
- resource: document
name: in_progress
kind: status-change
description: An author has claimed the document and work has begun.
- resource: document
name: in_review
kind: status-change
description: Work submitted and available for review.
- resource: document
name: incomplete
kind: status-change
- resource: document
name: completed
kind: status-change
description: Final content is available; retrieve it via the document's author_work URL.
- resource: document
name: paused
kind: status-change
- resource: document
name: canceled
kind: status-change
- resource: document
name: quality_control
kind: status-change
- resource: document
name: copyscape
kind: status-change
description: Plagiarism check stage (Copyscape is a named subprocessor).
- resource: document
name: counting_words
kind: status-change
- resource: document
name: word_count_finished
kind: task-completion
description: Triggered when the task of counting words on a document has successfully completed.
- resource: document
name: support_message_created
kind: activity
description: Triggered when a new message has been created on a document's support thread.
related_operations:
- GET /v1/clients/projects/{project_id}/documents/{document_id}/support_messages
- POST /v1/clients/projects/{project_id}/documents/{document_id}/support_messages
additional_callback_keys_in_spec:
note: >-
Three callback keys appear in the OpenAPI request schemas but are NOT in the documented event
tables. Recorded as observed, unconfirmed by docs.
keys:
- in_creation
- in_extra_review
- complete
caveat: >-
`complete` and `completed` both appear as document callback keys in the spec; only `completed`
is documented. Do not assume `complete` fires.
streaming:
present: false
note: No SSE, WebSocket or message-queue surface is documented or discoverable.
polling_alternative:
available: true
operations:
- GET /v1/clients/projects/{project_id}
- GET /v1/clients/projects/{project_id}/documents/{document_id}
- GET /v1/clients/projects/filter
provider_guidance: >-
Discouraged. "Always prefer using webhooks over HTTP polling for reliability." The stated
reason is payload size: fetching finished documents over the API risks the 30-second timeout,
whereas webhooks push the content to you.
Work with this as data
Every AsyncAPI spec here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for asyncapi
4 MCP tools reach this
find_asyncapisBrowse and filter every AsyncAPI spec in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
This AsyncAPI spec
curl "https://apis.io/api/v1/asyncapis/textmaster-event-surface"
All asyncapi
curl "https://apis.io/api/v1/asyncapis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.