This guide is the canonical human-readable path from a new operator account to a safely operated BOT integration. The machine contract remains openapi.yaml; webhook messages remain asyncapi.yaml. The current BOT Integration Terms are part of this contract and must be read before an integration is created.
1. Register an operator account#
- Open
https://integration.boringordertracker.com/register. - Enter the email address belonging to the person responsible for the integration. One account belongs to one person; teams and shared logins are not supported in v1.
- Open the one-time verification link sent by BOT. It expires after 20 minutes.
- Create a passkey with user verification, for example Face ID, Touch ID, Windows Hello, a password manager, or a FIDO security key.
- Save the recovery codes when they are displayed. They are shown once.
The portal never accepts or stores a password. A normal session expires after 20 minutes of inactivity or eight hours absolutely and is rotated while in use. Certificate requests, webhook changes, production submissions, review decisions, and account deletion require a recent passkey confirmation.
If a recovery code is used, all existing portal sessions and passkeys are revoked and a new passkey must be enrolled. Each recovery code is single-use.
2. Create an integration profile#
After sign-in, choose Create integration on the dashboard. One operator account may own multiple integrations; each is isolated and reviewed separately.
Before the portal may create an integration, the operator must explicitly accept the currently published version of the BOT Integration Terms. The acceptance is versioned; a new terms version requires a new explicit acceptance. An earlier checkbox or acceptance is never carried forward silently.
The standard integration licence is non-commercial only. Advertising, Google AdSense, sponsorships, affiliate revenue, subscriptions, paid access, lead generation, data licensing or resale, and every other direct or indirect form of monetization are commercial use. Commercial use is permitted only after BOT and the operator have made an individual written agreement covering that use. A sandbox client, review approval, owner activation, production certificate, or user consent does not replace that written agreement.
Supply all of the following:
- public name and a permanent, globally unique slug;
- public description and a specific purpose for using shared data;
- legal operator name, two-letter country code, and support email;
- public HTTPS website, privacy policy, terms of service, and order-linking URL;
- the smallest set of requested scopes;
- the planned polling cadence and optional webhook model;
- acceptance of the current BOT Integration Terms and the mandatory BOT attribution/app-link rules;
- an optional direct support or donation URL.
Every URL must be publicly reachable over HTTPS on port 443. The slug cannot be changed later. Public name, purpose, privacy URL, and scopes are consent-relevant: a material change creates a new profile/consent boundary and never widens an existing user's grant silently. During the current sandbox rollout, create a separate integration if the portal refuses a material profile change.
Available v1 scopes are:
orders.read— current allowed order snapshot;orders.history.read— complete allowed order change history;vehicles.read— current allowed snapshot of a specifically selected stock vehicle;vehicles.history.read— allowed, deduplicated stock-vehicle history;shipping.read— minimized vessel, voyage, port, and shipping events for a granted order;statistics.orders.read— fixed, thresholded aggregate generations only;revocations.ack— deletion acknowledgements.
Creating the profile immediately creates a separate sandbox client, baseline quota, approved sandbox scopes, and queues an integration-specific synthetic corpus. A private worker validates and atomically activates exactly 500 synthetic orders plus 50 synthetic existing vehicles; the web request does not materialize them. No BOT user, production order, VIN, or production vehicle is copied into it.
3. Upload the integration logo#
Open the integration detail page and upload a PNG, JPEG, or WebP image. SVG is not accepted. The source must be no larger than 2 MiB and both dimensions must be between 256 and 2048 pixels. BOT decodes the image, removes metadata, and generates safe 256- and 512-pixel renditions in non-executable storage.
The logo is required before a production review can be submitted. Use a mark you are legally entitled to publish.
4. Obtain a sandbox mTLS certificate#
The portal and machine API have separate trust boundaries. Browsers authenticate to integration.boringordertracker.com with a passkey. Servers authenticate to api.integration.boringordertracker.com with a BOT-issued client certificate.
Use one of two issuance modes from the Certificates section:
- CSR, recommended. Generate and retain the private key on your own server, then paste a PEM PKCS#10 CSR. RSA 3072–8192 and EC P-256/P-384 keys are accepted. Download the issued public certificate and CA chain.
- One-time encrypted P12. BOT generates the key in private worker memory. Save the one-time claim token, then claim the encrypted package and its password within 15 minutes. Both are shown once and BOT does not retain an unencrypted private key.
Certificate issuance is asynchronous. Refresh the integration page until the request is ready. Certificates last 90 days. Up to two certificates may overlap for a 14-day rotation; quotas remain integration-wide. Revoke a compromised or retired certificate immediately in the portal.
See mTLS certificates for key handling, rotation, and edge/backend verification details.
5. Exercise the synthetic sandbox#
Open Sandbox from the integration detail page. The fixture set is private to that integration and contains only resources allowed by its requested scopes:
- active synthetic order and/or stock-vehicle snapshots;
- complete allowed history events;
- a retained revocation tombstone;
- a fixed privacy-thresholded statistics generation;
- initial sync, incremental sync, deletion acknowledgement, and ETag scenarios.
Use the same API base URL in both environments:
https://api.integration.boringordertracker.com/v1
The presented client certificate selects sandbox or production. Never try to select an environment with a request parameter or header.
Recommended smoke sequence:
- call
GET /capabilitiesand assertenvironmentissandbox; - generate a ten-digit code on the portal's Sandbox page;
- redeem it once with
POST /link-codes/redeem, preserving leading zeroes; - call
GET /syncwithout a cursor and transactionally apply the full page; - follow each
next_cursorunchanged and testIf-None-Match/304; - fetch order/vehicle detail and every history page for the granted scopes;
- process the tombstone, delete the local individual copy, and acknowledge it with a stable
Idempotency-Key; - if requested, read the fixed statistics generation and verify that it contains no individual records.
Do not hard-code fixture IDs or ten-digit codes. They are scoped to the integration and may be regenerated. Tested curl, PHP, Node.js, and Python examples are linked from the documentation home page.
6. Build the public linking and privacy experience#
Before review, implement a public staging version of the operator-side flow. It must explain that the user deliberately shares selected BOT resources and must include:
- a My Order or equivalent page that accepts the ten-digit BOT code as a string;
- no request for the user's BOT login, account ID, real order number, or VIN;
- the mandatory BOT attribution text and BOT app link supplied by the portal, displayed prominently and readably wherever BOT data is shown;
- working links to the operator's privacy policy, terms, and support contact;
- deletion behavior for resource and connection revocations;
- a clear separation between a linked personal order and aggregate statistics.
If a page, table, list, card, chart, export, notification, or other output mixes BOT data with data from another source, mark every BOT-derived record or entry directly at its output point. For an aggregate visualization, identify each BOT-derived series or result where it is rendered. A generic footer, legal page, or page-wide credit alone is not sufficient to identify mixed-source data.
The code is not a durable user identifier. Redeeming it yields only a random connection ID and random integration-specific resource IDs. A different integration receives different IDs for the same underlying BOT resource.
Install the standard footer credit#
Add the versioned, tracker-free badge to the public footer:
<footer>
<span data-bot-attribution data-bot-theme="auto"></span>
<script src="https://integration.boringordertracker.com/assets/bot-data-credit-v1.js" referrerpolicy="no-referrer" defer></script>
</footer>
The script sets no cookies, contains no analytics, and renders “Data provided by Boring Order Tracker with user consent”. Keep referrerpolicy="no-referrer" so the partner page URL is not sent with the asset request. Use auto, light, or dark; when no placeholder is present, the badge is inserted directly beside the script. This site-wide badge does not replace the per-record, per-value, per-map-point, per-chart-value, and per-export attribution required above for mixed-source output.
7. Request production review#
Complete this checklist before selecting Submit for production review:
- all profile and policy fields are accurate and publicly reachable;
- the sanitized logo is uploaded;
- only necessary scopes are requested;
- the public linking flow works with synthetic data;
- BOT attribution and the app link are visible on the submitted review page;
- the current Integration Terms version is accepted and the intended business model is declared accurately;
- the standard non-commercial licence covers the intended use, or an individual written BOT agreement covering commercial use is already in place;
- mixed-source staging output identifies every BOT-derived record, entry, series, or result at its output point;
- the polling/webhook concept describes storage, retries, and deletion handling;
- your backend passes the sandbox lifecycle and rate-limit tests;
- your privacy policy describes the requested data, purpose, retention, and revocation path.
The submission action requires a fresh passkey confirmation and a public HTTPS review URL. The integration then enters submitted; the current profile is frozen for review.
BOT manually checks operator identity, purpose, policies, branding, linking, requested scopes, storage/deletion behavior, security model, and attribution. BOT also checks the declared business model against the applicable licence or individual written agreement. BOT may reject the submission with review notes. Correct the issues and submit again. Approval is limited to the reviewed profile version and exact scopes.
8. Understand approval versus activation#
The statuses have distinct meanings:
draft/sandbox— profile work and synthetic API access;submitted— waiting for manual BOT review;rejected— changes are required before resubmission;approved— the reviewed production profile/scopes are accepted and a production certificate or production webhook may be prepared;active— after BOT approval, the integration owner has explicitly pressed Activate for production for that exact reviewed profile;suspended,retired— production access is stopped.
approved is not the same as active. Production API authentication requires the integration to be active. Even then, the independent production_data_enabled capability must be true, and only resources explicitly granted and uploaded by users can appear. During the current rollout this gate is false, so production link, sync, detail, history, statistics, and data webhook payloads are unavailable.
After approval, the owner sees a prominent Activate for production action in the dashboard and integration detail. That action changes the reviewed profile from approved to active and makes it eligible for the mobile catalogue. It does not enable the independent BOT production-data gate. BOT can suspend an integration immediately, and administrators can activate or reactivate it for operational recovery.
The separate data gate is enabled only after the mobile consent/upload release, legal and operational checks, production credential tests, rollback tests, and an explicit BOT go-live decision. Neither approval nor owner activation can bypass it. These states also do not grant commercial-use rights; the separate written agreement remains mandatory whenever the integration or surrounding service is monetized.
9. Prepare production separately#
After approval, request a new production certificate. Never reuse the sandbox key/certificate, resource IDs, cursor, ETag, cached data, or webhook endpoint state in production. Confirm through GET /capabilities that the certificate is bound to the expected environment, scopes, quotas, status, and production-data gate before reading anything else.
Pull is the canonical and recoverable transport. Start without a cursor, commit the whole returned page locally, then store next_cursor. Poll every 15 minutes unless the capability response documents an approved override.
Each upsert is a complete permitted projection, not a patch. Apply by monotonic revision and resource ID. History is independently paginated. Treat history_complete=false as a hard incomplete marker.
10. Optional webhooks#
An integration can register up to three public HTTPS endpoints in each permitted environment. Choose explicit events and either notification or full_payload. BOT verifies endpoint ownership before activation. Redirects, private/reserved addresses, unsafe DNS changes, and oversized responses are refused.
Verify Content-Digest and the Ed25519 HTTP Message Signature before parsing the body, enforce timestamp freshness, and deduplicate the event ID. Return a 2xx only after durable acceptance. Pull sync remains the recovery source after downtime, reordering, or a missed event.
During the current public sandbox rollout, scheduled webhook delivery is not a production-available channel. Do not make webhooks a go-live dependency until the portal and BOT explicitly show that the delivery worker is enabled for your environment.
See webhook operations and the downloadable AsyncAPI contract.
11. Handle consent and revocation correctly#
Users grant exact orders and, optionally, exact stock vehicles for one integration. Statistics participation is a separate opt-in for that exact integration. The API response is always the intersection of the global allowlist, reviewed scopes, current grant, and environment/client scopes.
Revocation blocks access immediately. A tombstone appears in the next sync and may also produce a minimal webhook. Delete all individual copies and derived individual data, then call POST /revocations/{id}/ack within seven days. Use a stable Idempotency-Key; acknowledgements are retry-safe. An outstanding deletion is warned at day five and can suspend production at day seven.
Never infer that a resource remains authorized merely because it still exists in a local cache. The current sync/tombstone state is authoritative.
12. Operate within quotas and failure contracts#
Baseline limits are 600 pull/detail requests per integration/hour, burst 20 per minute, four concurrent requests, 500 records, and 8 MiB per response. Statistics use 120 requests/hour and 2 MiB. Link-code redemption is additionally limited to 60 attempts per integration/hour and 10 per source IP/15 minutes. Approved overrides appear in GET /capabilities.
Inspect the rate-limit headers on every response. On 429, honor Retry-After. API errors use RFC 9457 application/problem+json with a stable code and diagnostic request_id. Treat 401/403 as a certificate, status, environment, or scope problem; treat 410 as a deletion requirement; retry 503 only with bounded exponential backoff.
Monitor certificate expiry, quota usage, last successful sync, cursor commit, history completeness, outstanding deletion acknowledgements, webhook dead letters, and the current BOT webhook JWKS key IDs. The portal shows usage and the deletion queue.
13. Data boundary#
The API never returns a VIN value, real order number, BOT account/contact/address or financing/payment data, Tesla IDs/tokens/credentials, raw provider payloads, GPS/calendar/vehicle name, or door/window/lock and other presence-sensitive live state. Individual data never enters the statistics endpoint.
Do not ask BOT to widen the contract through internal app interfaces or scrape another BOT surface. A new field, scope, or purpose requires a reviewed profile version and, where applicable, renewed user consent.
See the field catalogue, consent and revocation, and versioning policy for the normative boundaries.
14. Keep licence, attribution, and terms acceptance current#
Continue to comply with the BOT Integration Terms for the entire integration lifecycle. When BOT publishes a new version, the operator must review and explicitly accept that version; an old acceptance does not cover the new text.
The default licence remains non-commercial. Do not add ads or AdSense, paid features, subscriptions, sponsorships, affiliate monetization, resale, or any other direct or indirect monetization without an individual written agreement with BOT first. Notify BOT before the business model changes so the integration can be reviewed against the correct agreement.
Keep the BOT credit and app link conspicuous, readable, and close to the data it describes. Mixed-source output must continue to identify each BOT-derived record, entry, series, or result at the point of display, including in exports and other user-visible output. Review these requirements whenever the layout, data source, presentation, or monetization model changes.