Start connecting a Drupal Commerce site
The first call of Decionis for Drupal's connect, made by the module with
no credential. It registers the site's Ed25519 public key and answers a
one-time challenge for the site to serve, signed, at
/.well-known/decionis-challenge (see connect/verify).
A public HTTPS site on the default port is proven by that challenge. A
site Decionis cannot reach (a private or local host, plain HTTP or a
port) is accepted too, and can be proven only by the 6-digit code
connect/verify emails to billing_email. A public host over plain
HTTP or on a port is refused. Nothing is ever fetched from a private
address.
Not idempotent: each call starts a new connect with a new challenge,
valid for expires_in_seconds; an unfinished connect expires. Requests
are limited per address and per site, and a refused one answers 429
with Retry-After.
Request Body
application/json
The site's base URL.
urilength <= 2048The Drupal site UUID (system.site uuid). A site Decionis cannot reach is bound by it, as drupal://site/.
1 <= length <= 1281 <= length <= 200Where the 6-digit code is sent if the site cannot be reached.
emaillength <= 320The site key's raw 32-byte Ed25519 public key, base64url without padding.
^[A-Za-z0-9_-]{43}$Response Body
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/drupal/connect/start" \ -H "Content-Type: application/json" \ -d '{ "site_url": "http://example.com", "site_uuid": "string", "business_name": "string", "billing_email": "user@example.com", "public_key": "string", "terms_accepted": true }'{ "connect_id": "a1b4c748-916a-48f3-ac78-f681f542c9c8", "challenge": "string", "expires_in_seconds": 1}Read Business Central sales history for reconciliation GET
Default off with the native Business Central reader. Ordinary workspace key with decision:read and decision:write and current native READ authority. Reads the extension's fixed read-only sales pages (1.0.2.4) for open sales orders by Order Date and posted sales invoices by Posting Date, for a window of at most 92 days. Identifiers are company-scoped SHA-256 digests; document numbers, order numbers and External Document No. never leave Core. The External Document No. is digested exactly as Business Central stores it. Amounts exclude tax, in integer minor units of the document currency. A read capped at 4,000 orders or 8,000 invoices sets coverage.truncated with a reason. When the connected extension does not publish a page (older than 1.0.2.4), that list is empty and coverage is incomplete with SALES_ORDER_PAGE_NOT_INSTALLED or SALES_INVOICE_PAGE_NOT_INSTALLED; no sale is inferred. A negative document is left out with NEGATIVE_SALES_DOCUMENTS_EXCLUDED. Nothing is written.
Prove a Drupal site by its challenge, or have a code emailed POST
Signed with the site key: `signature` is the Ed25519 signature, in base64url, over the key-sorted canonical JSON of the body without `signature`. For a reachable site, Decionis fetches `https://<site>/.well-known/decionis-challenge` over HTTPS with no redirects, a five-second budget and a 16 KB cap. The site answers a JSON object with `protocol` (`decionis-drupal-connect/1`), `purpose` (`challenge`), `connect_id`, `site_url`, `challenge`, and `signature`: the site key's signature over the rest, signed the same way. A match claims the challenge, once, and connects the site (200). A site that answers without a valid proof is refused (403 DRUPAL_CHALLENGE_FAILED) and is not offered a code. For a site Decionis cannot reach, or that gives no answer at all, a 6-digit code is emailed to the billing address instead (202); finish with `connect/code`. Until a code sender is configured, that answers 503 DRUPAL_EMAIL_CODE_UNAVAILABLE. Connecting binds the site to one Decionis organization for good, creating it the first time, and answers that organization's least-privilege key (role MEMBER, scopes decision:read and decision:write) exactly once: only its hash is kept. Proving a connected site again issues a new key and revokes the one it had. The site starts in Shadow. The challenge is single-use. A second verify of a used challenge answers 409 DRUPAL_CHALLENGE_ALREADY_USED, and a connect that has connected, failed or sent a code answers 409 DRUPAL_CONNECT_NOT_PENDING: start a new one. When Decionis refuses to bind the site, the answer carries that status with UPSTREAM_UNAVAILABLE.

