SafetyDataSheetAPI is a product of Dscvry. Explore Dscvry →

Evidence

API Changelog

Dated changes to the SafetyDataSheetAPI endpoints, response contract, and documentation. Deprecation notices are announced here first, following the deprecation lifecycle.

Last updated: 2026-10-23 · Machine-readable contract: /openapi.yaml

2026-10-25

  • Added: Buy credit by card in the dashboard (Billing): packs of $25, $100 and $500, priced in USD, GBP or EUR through Stripe, with VAT added where it applies, a VAT number field for businesses and an invoice for every payment. Purchased credit is valid for 12 months; unused credit expires after that and the dashboard warns before it does. Credit is spent soonest-expiring first.
  • Added: Per-customer API keys (sds_live_...) with a prepaid credit balance. Each document is billed at $0.25 per 40 pages (rounded up) from the balance; failed extractions are not billed. New error codes: 402 insufficient_credit (balance, required amount, pages and documents billed are returned beside error), 413 too_many_pages (limit 400 pages), 401 api_key_revoked and 403 account_suspended. Successful responses to per-customer keys carry a billing object. Keys are limited per key (60 requests a minute by default).
  • Added: GET /api/account and the MCP tool get_account return the balance, price and 30-day usage for the key's account. MCP server version 1.1.0.
  • Changed: Keys issued before this release (the shared enterprise key) keep working unmetered.

2026-10-24

  • Added: document_language in single-extraction responses, at the top level and in metadata: the language the document is written in, detected from the document (for example sv or pt-BR), or null when it cannot be determined. It is separate from language_hint, which only echoes the hint you sent. Bulk job items do not carry it yet.
  • Changed: Transient failures of the extraction service (temporary unavailability, rate limiting, or an unreadable answer) are now retried up to twice before a provider_error is returned. Requests that are invalid, blocked, or cut off at an output limit are not retried.
  • Added: A fixed output schema (version 1.0: 16 sections, about 100 fields including storage class, water hazard class, VOC content, SVHC substances and per-mode transport data) can be enforced for a deployment. When it is on, outputs.json always has exactly the same keys in the same order, missing values are null, metadata.schema_version is 1.0, and responses carry is_safety_data_sheet; non-SDS documents are flagged with a warning. It is on for all extractions as of 2026-10-24.
  • Added: schema_version can be sent as a form field to pin the output schema; only 1.0 is supported and any other value returns 400 unsupported_schema_version. Responses now include schema_version at the top level, and bulk items include document_language and schema_version. The fixed schema is now on for all extractions. Example values such as 2026-01 that appeared in older documentation are not valid.
  • Fixed: A response from the extraction model that stopped before finishing (for example at an output limit) now returns a provider_error instead of partial data.
  • Changed: The extraction request is now deterministic (temperature 0) and instructs the model to copy text verbatim and include every list item and table row. This is aimed at shortened output and run-to-run differences; it does not by itself fix field-name variation inside sections, which needs a fixed schema (planned).
  • Added: Remote MCP server at https://safetydatasheetapi.com/mcp (Streamable HTTP, stateless) with tools extract_sds, submit_bulk_extraction, and get_bulk_job. Same API key, rate limits, and error codes as the REST API. See SDKs and agents.
  • Added: Agent skill (discovery index), OAuth protected resource metadata, an x-agentic-access section and a typed webhooks definition (bulk_extraction.completed) in the OpenAPI contract.
  • Security: Webhook callback_url validation is stricter: it now rejects IPv6 literals, link-local and cloud-metadata addresses, the whole 127.0.0.0/8 range, carrier-grade NAT, reserved ranges, single-label and internal host names, and URLs with embedded credentials.
  • Added: Official clients and Postman collection: a single-file Python client, a single-file JavaScript client, and a Postman collection with saved examples and test scripts. Each covers single extraction, bulk jobs with Idempotency-Key, job polling, typed errors with Retry-After, and webhook signature verification.
  • Removed: The provider object (name, model) is no longer returned in successful extraction responses. It identified the upstream model vendor, was not part of the documented output contract, and is not needed to consume results. Clients that read it should stop; no other response fields changed.
  • Security: Server-side failures (provider_error, provider_not_configured, output_processing_failed) now return a generic message and a request_id only. They no longer include upstream provider names, raw provider responses, configuration hints, or internal exception text. This also applies to failed items in bulk job status and webhook payloads. The provider_status, provider_error, provider_hint, provider_response, and provider_model_attempts fields are removed from error bodies.
  • Docs: Bulk job items now document error_code and error_message, and the job documents webhook_attempts.

2026-10-23

  • Added: Provider-published discovery files: /apis.yml, /.well-known/apis.json, and an RFC 9727 /.well-known/api-catalog, also advertised from the homepage in a Link: rel="api-catalog" header.
  • Fixed: Unknown URLs (including unknown /.well-known/* paths) returned 200 with the homepage HTML. They now return a proper 404.
  • Added: Retry-After header (seconds) on every 429 rate_limited response, alongside the existing retry_after_epoch_seconds body field.
  • Docs: openapi.yaml rewritten as OpenAPI 3.1 with a shared error envelope, rate-limit headers, both auth schemes, and request/response examples.
  • Docs: The spec no longer claims application/xml or text/csv responses from /extract-sds. It always returns JSON, with XML and CSV inside outputs. This describes existing behavior; no API behavior changed.
  • Docs: The API docs error table now lists the codes the API actually returns, and a rate limits section was added.
  • Docs: Example URLs now use https://safetydatasheetapi.com/extract-sds. The separate api.safetydatasheetapi.com host never resolved and was removed from the docs and spec.

2026-09-16

  • Added: Asynchronous bulk extraction: POST /extract-sds/bulk (up to 10 files, 202 with a job id) and GET /extract-sds/bulk/{jobId}, with optional signed webhook delivery (X-Webhook-Signature), Idempotency-Key support, and per-file and per-job size limits.
  • Fixed: Intermittent raw 502 responses on the sample upload flow. Failures while formatting extraction output now return a clean 500 output_processing_failed JSON error.
  • Security: /extract-sds now fails closed (503) when no API key is configured; stricter bot verification and rate limiting on website endpoints; CSV output neutralizes spreadsheet formula injection; PDF signature validation on uploads.
  • Privacy: Removed a third-party visitor-tracking script from all pages.
  • Added: Self-serve API access signup on the homepage.

Deprecations

No fields or endpoints are currently deprecated. Future deprecations will be listed here on day 0 with a migration mapping and a removal date, and honor the support windows in the schema versioning policy.

Related pages