This is the reference for the Trustico® Partner Ordering API. Use it to place SSL Certificate orders that are paid from your Trustico® Prepaid Credit and processed like any other Trustico® order.
Quick Start
Ordering requests carry an X-Api-Key header identifying your account and an Idempotency-Key header protecting you from duplicate orders. The two product lookup endpoints are public and need no key ; the order lookup carries your key.
The three fields below feed every example on this page. Enter your API key, pick a SKU from the Orderable Products table, and set the domain you want the SSL Certificate issued for : each curl, JavaScript and Python example then rewrites itself around your values. The lookup examples can be copied and run exactly as shown ; the order example additionally needs your own Certificate Signing Request pasted in place of the placeholder, so that it is never run by accident.
Your API key is used only inside your browser to build the example text : this page never stores it and never sends it anywhere.
API access requires approval prior to use. To apply for a Partner API key, or if you believe a key has been compromised, contact your SSL Certificate provider. Revoking a key takes effect on your next request.
How Ordering Works
Look up the orderable products with GET /api/skus, then confirm your chosen SKU and read its field vocabulary with GET /api/sku/{sku}.
Submit the order with POST /api/orders. The order is priced against your account and paid from your Trustico® Prepaid Credit : it is created already paid, with no invoice step.
The ordering and order lookup endpoints are server-to-server only : browsers cannot call them. The two product lookup endpoints may be called from anywhere.
Authentication
Every ordering and order lookup request carries your issued key in the X-Api-Key header. A missing header answers 401 with a distinct message ; an unknown, revoked, or otherwise not-accepted key answers 401 with one identical message, deliberately, so the response never reveals why a key was refused.
Keys are account credentials : anyone holding your key can place orders paid from your Trustico® Prepaid Credit. Store it as a secret, never in client-side code.
The Idempotency-Key Header : Your Safety Contract
Every ordering request carries an Idempotency-Key header : 1 to 128 printable ASCII characters, compared case-sensitively (Key and key are different requests). Do not rely on leading or trailing whitespace to make two keys different. One key means one order intent, for as long as you present it with the same X-Api-Key.
Replays are safe. The same key with the same body always returns the current truth of that one request : never a second order, never a second charge.
The same key with a different body answers 409 IDEMPOTENCY_CONFLICT : fix the body under a new key.
Never mint a fresh key to retry a timeout. A 504, a network error, or a client timeout means the outcome is unknown : the order and the charge may have landed. Retrying with the same key resolves it ; a fresh key is the one way to double-order through this API.
Never re-send an Idempotency-Key under a different API key. The protection is remembered against the API key the request arrived with, so a replacement key does not know your previous key's requests and would place a second order. The other side of that is deliberate and useful : a replacement key is a clean slate, so you may restart your own request numbering on it. When your key is replaced, let every in-flight retry finish on the old key before you switch.
Orderable Products
The table below is generated from GET /api/skus each time this page loads : the same product list the ordering endpoint enforces, so the two cannot drift apart.
Construct a SKU from the family, a three-digit SAN count where the family carries one, and a term : T-DVTMD + -002 + -12 gives T-DVTMD-002-12. Confirm any constructed SKU with GET /api/sku/{sku} : its isSellable field is the authoritative answer.
| Product Name | SKU Family | Terms (Months) | SAN Counts | Example SKU |
|---|---|---|---|---|
| Loading the Product List | ||||
Endpoints
/api/skus
PublicList Orderable Products
The orderable-product catalog : one row per product family.
Returns every orderable product family : the product name, the validity terms in months, the SAN-count range for multi-domain families, and one real example SKU. The list is generated from the same product data the ordering endpoint enforces, so it always matches what POST /api/orders accepts.
Multi-domain families carry a sanCounts range and their SKUs carry a three-digit SAN-count segment ; single-site families carry sanCounts: null and no SAN-count segment.
Access : No authentication. The route is rate limited per IP.
Truncated for display : the live response carries one row for every orderable family.
Code Example
Rate Limits
Burst : 10 / second / IP
Sustained : 300 / hour / IP
/api/sku/{sku}
PublicGet SKU Configuration
The per-SKU facts : sellability, product name, field vocabulary, DCV methods, and the domain limit.
Returns the full configuration for one SKU. isSellable is the authoritative answer to whether the SKU can be ordered, and productName is the product name (null for SKUs not on sale).
requiredFields and optionalFields are the exact fields vocabulary POST /api/orders accepts for the SKU. dcvMethods lists the validation methods the SKU may use, and maxDomains is the domain limit an order may not exceed.
The response carries further fields that drive the Trustico® order forms ; an ordering integration only needs the fields named above.
An unknown or malformed SKU answers 400 with code SKU_UNKNOWN.
Access : No authentication. The route is rate limited per IP.
Truncated for display : the live response carries additional form-driver fields an ordering integration does not need.
Code Example
Rate Limits
Burst : 10 / second / IP
Sustained : 300 / hour / IP
/api/orders
API KeyPlace an Order
Create an SSL Certificate order, paid from your Trustico® Prepaid Credit.
One product per request, quantity 1. The request carries three headers : Content-Type: application/json, your X-Api-Key, and an Idempotency-Key (see the safety contract above).
The primary domain plus every Additional FQDN entry may not exceed the SKU's advertised maxDomains : an over-count order is refused up front with both figures named, never accepted and failed later.
Every domain you supply, the primary and each Additional FQDN entry, must be a well-formed domain name. A malformed one is refused up front and named, never accepted and failed at issuance. Additional FQDN entries may be separated by commas or whitespace.
An internationalised domain may be sent in either form when you validate by DNS or by file : send köln.de or its punycode xn--kln-sna.de and it is converted for you. When you validate by e-mail, send BOTH the domain and the approver address in punycode : xn--kln-sna.de with admin@xn--kln-sna.de. The approver list is calculated from the ASCII name, so the Unicode form of a domain has no approver addresses at all and every address is refused against it, naming that domain.
The example body below shows a typical Domain Validated order. Build your own fields from what GET /api/sku/{sku} advertises for your SKU.
Access : Requires your issued X-Api-Key. Server-to-server only : browsers cannot call this endpoint.
Request Body
sku (required) - A sellable SKU. See GET /api/skus for the catalog, and confirm with GET /api/sku/{sku}.
fields (required) - An object of field label / value pairs. The vocabulary is exactly what GET /api/sku/{sku} advertises for your SKU (requiredFields + optionalFields), plus the two validation fields below where the SKU advertises DCV methods. Unknown field labels are refused, never ignored : a typo cannot silently weaken an order.
Validation Token (conditional) - How your PRIMARY domain proves ownership. One value, and it is EITHER one of the SKU's advertised dcvMethods verbatim (HTTP, HTTPS, DNS_CNAME, DNS_TXT) OR an approver e-mail address, which is how you choose e-mail validation : there is no separate method field, because an address already says which method it is. An address must be one of the standard construction addresses for that domain : admin@, administrator@, hostmaster@, postmaster@ or webmaster@, at the domain itself or at any parent domain down to the registrable domain. Sending the literal word EMAIL is refused : send the address instead. Required whenever the SKU advertises DCV methods.
Validation Tokens (conditional) - How each ADDITIONAL domain proves ownership. Required exactly when Additional FQDN is present : comma-separated, positional, one entry per additional domain, in the same order. Each entry follows exactly the same rule as Validation Token above, applied to ITS OWN domain : a method the SKU advertises, or an approver address for that domain. You may mix them freely.
A fresh completion answers 201. A replay or a recovered request answers 200 with the same body shape and the same order.
Code Example
Rate Limits
Burst : 10 / second / IP
Sustained : 60 / hour / IP
Per API Key : 60 / hour
Responses and Retry Directions
| Status | Code | What Happened | What You Do |
|---|---|---|---|
| 400 | VALIDATION_FAILED / SKU_UNKNOWN / INCOMPLETE_DCV_SET / INVALID_JSON | The request was refused before any money moved ; the message names the field or domain | Fix the body, submit under a NEW key (the old key replays the same refusal) |
| 400 | VALIDATION_FAILED | The Idempotency-Key header is missing, or is not 1 to 128 printable ASCII characters. Nothing is recorded : that header is what identifies the request | Add or correct the header and retry. The key is still unused, so it is not spent |
| 401 | UNAUTHORIZED | Key missing or not accepted | Check the key ; contact your SSL Certificate provider |
| 402 | INSUFFICIENT_CREDIT | Your balance (plus any overdraft) does not cover the order ; the response carries shortfall: { currency, amount } and the order is held for you | Top up your Trustico® Prepaid Credit so the shortfall is covered. The response names the currency it is quoted in ; that currency, or the currency your account is denominated in, will release the order. Then retry the SAME key : the held order is re-checked on your fresh balances |
| 409 | REQUEST_IN_PROGRESS | This key's request is executing right now | Wait briefly, retry the SAME key |
| 409 | IDEMPOTENCY_CONFLICT | The key was already used with a different body | Use a NEW key |
| 409 | TOTAL_MISMATCH | The held order's total changed while held ; your credit is debited and SAFE | Do NOT loop this key : the same answer repeats until resolved. Contact your SSL Certificate provider |
| 410 | DRAFT_GONE | The held order no longer exists ; any debit was already returned to your balance | Submit again with a NEW key if still wanted |
| 413 | BODY_TOO_LARGE | The request body is over the size limit | Reduce the body and retry |
| 415 | UNSUPPORTED_MEDIA_TYPE / UNSUPPORTED_ENCODING | The Content-Type is not application/json, or the encoding or charset is not plain UTF-8 | Send plain UTF-8 JSON and retry |
| 429 | RATE_LIMITED | A rate ceiling was reached ; the response carries Retry-After | Wait the Retry-After seconds, then retry |
| 502 | UPSTREAM_REJECTED | The order could not be priced or placed (catalogue or configuration) | Contact your SSL Certificate provider |
| 503 | SERVICE_UNAVAILABLE | An infrastructure failure ; the order was not placed. Rarely, payment state is left unresolved until you retry | Retry the SAME key : the retry settles any payment state |
| 503 | GATEWAY_CONFIG | Payment configuration is unavailable ; your credit is debited and SAFE | Retry the SAME key periodically : it completes once configuration is restored |
| 503 | COMPLETION_UNKNOWN | Payment is debited and SAFE ; the completion's outcome is unknown | Retry the SAME key : the retry resolves it |
| 500 | INTERNAL_ERROR / INTERNAL | An unexpected failure | Retry the SAME key |
| 504 | GATEWAY_TIMEOUT | The request timed out : THE OUTCOME IS UNKNOWN and processing may still finish (an edge timeout may carry no body at all) | Retry the SAME key. Never a fresh key (see the safety contract above) |
The three post-payment rows pull in two directions, deliberately : GATEWAY_CONFIG and COMPLETION_UNKNOWN are same-key retries (your money is safe and the retry completes the order) ; TOTAL_MISMATCH is not retryable (the same refusal repeats while a human resolves it).
/api/orders
API KeyLook Up Your Orders
Your API-placed orders, each SSL Certificate carrying its CA Reference : the tracking system handoff.
Returns your newest 100 order requests, newest first : each with its requestId, its status (processing / held / completed / refused / failed), the order name, and a certificates array carrying the domain, the SKU, the Certificate status (processing / submitted / failed), the caReference, and the brand.
To walk further back than one page, repeat the call with before set to the requestId of the LAST order on the page you hold : each call answers the next older page of the same size, until the page comes back empty. The value is simply echoed from our own response : you never construct it, and a before we do not recognise answers 400 rather than an empty page.
The caReference is assigned by the Certificate Authority shortly after the order completes and is null until then : poll this endpoint until it appears. For SSL Certificates, together with the domain and brand values, it is exactly what the tracking system API authenticates with.
caReference is returned for every product family, but it is a tracking system credential only on traditional SSL Certificates. On Certificate as a Service (CaaS) orders the value identifies the license at the Certificate Authority (CA) and nothing more : those SSL Certificates are managed through your own ACME client, so a tracking system API call carrying that reference is refused. Use it for support and reconciliation rather than for authentication.
Returns orders placed through this API. Orders placed directly in the store are not included : their CA References are delivered through the standard order channels.
GET /api/orders/{requestId} returns one request by the requestId the ordering call answered with ; an unknown reference answers 404.
A requestId is an opaque reference : req_ followed by 32 hexadecimal characters. Store it as text and pass it back unchanged : it carries no meaning, no order, and nothing to parse.
Every key issued for the same account sees the same orders : replacing a key never hides your order history.
Access : Requires your issued X-Api-Key. Server-to-server only : browsers cannot call this endpoint.
The by-id form answers { "order": { ... } } : one entry of the same shape under the order key. A Certificate still awaiting the Certificate Authority carries status: "processing" and caReference: null.
Code Example
Rate Limits
Burst : 10 / second / IP
Sustained : 300 / hour / IP
Per API Key : 300 / hour
Responses and Retry Directions
| Status | Code | What Happened | What You Do |
|---|---|---|---|
| 400 | VALIDATION_FAILED | The before parameter is not a requestId of yours | Pass the requestId of the last order on your previous page |
| 401 | UNAUTHORIZED | Key missing or not accepted | Check the key ; contact your SSL Certificate provider |
| 404 | NOT_FOUND | The requestId does not exist for your account | Check the requestId your ordering call answered with |
| 429 | RATE_LIMITED | A polling ceiling was reached ; the response carries Retry-After | Wait the Retry-After seconds, then continue polling |
| 500 | INTERNAL_ERROR / INTERNAL | An unexpected failure | Retry shortly |
| 503 | SERVICE_UNAVAILABLE | An infrastructure failure before your key was checked | Back off briefly, then retry |
| 504 | GATEWAY_TIMEOUT | The request timed out (an edge timeout may carry no body at all) | Retry |
After Success
The order processes exactly like any Trustico® order : validation, issuance, and the standard order confirmation e-mail.
Your Trustico® Prepaid Credit dashboard and statement show the payment against the real order number.