Moving from the organization API key
Until now, scripts could call the web app’s own routes (/{organization}/api/v1/…) with one shared organization key in the x-api-key header. That key is deprecated:
- Every response to it carries
DeprecationandLink: <https://tradecrafthub.ai/docs/api/migrate-from-api-key/>; rel="deprecation"(this page). From the launch it also carriesSunset: <launch + 90 days>, the date the key stops working. - Each use is recorded in the audit log (
legacy_api_key_used). - Admin → API → Settings shows The organization API key is deprecated, with when it was last used and when it stops working (90 days after the launch; the date once the API has launched).
- The key acts as a member with the User role only, and only for reads plus uploading, Analyze, Process and asking a question. It is never accepted on
api.tradecrafthub.ai.
Move a script in four steps
Section titled “Move a script in four steps”- Turn the API on: Admin → API → Settings → Allow the Tradecraft API.
- Create a machine client in Admin → API → Clients → New API client → Machine client. Pick the acting role and the scopes the script needs (table below). Store the client secret where the old key was.
- Get a token with client credentials and send it as
Authorization: Bearer …. Tokens last an hour: request a new one when it expires. - Change the URLs to
https://api.tradecrafthub.ai/v1/…. Your organization is no longer in the path: it comes from the token.
# Beforecurl -s -H "x-api-key: $TRADECRAFT_KEY" "https://tradecraft.m11solutions.com/acme/api/v1/assessments"
# AfterTOKEN=$(curl -s -u "$CLIENT_ID:$CLIENT_SECRET" -d grant_type=client_credentials \ https://api.tradecrafthub.ai/oauth/token | jq -r .access_token)curl -s -H "Authorization: Bearer $TOKEN" "https://api.tradecrafthub.ai/v1/assessments"// Before: fetch(`https://tradecraft.m11solutions.com/acme/api/v1/assessments`, { headers: { "x-api-key": key } })const token = await getToken() // client credentials, see Machine clientsconst res = await fetch("https://api.tradecrafthub.ai/v1/assessments", { headers: { Authorization: `Bearer ${token}` } })Where each call goes
Section titled “Where each call goes”Paths with the key were /{organization}/api/v1/…; on the API they are /v1/….
GET /assessments→GET /v1/assessments(assessments:read)GET /assessments/{id}→GET /v1/assessments/{id}andGET /v1/assessments/{id}/questions(assessments:read)GET /assessments/{id}/download→GET /v1/assessments/{id}/download(assessments:read)POST /assessments→POST /v1/assessments, with anIdempotency-Key(assessments:write)POST /assessments/{id}/analyze→POST /v1/assessments/{id}/analyze, with anIdempotency-Key(assessments:write)POST /assessments/{id}/process→POST /v1/assessments/{id}/process, with anIdempotency-Key(assessments:write)POST /security-center/ask→POST /v1/ask(knowledge:ask)GET /knowledge/answers→GET /v1/answers(knowledge:read)
What is different
Section titled “What is different”- Responses have their own, stable shapes. Check the fields your script reads against the reference; the web app’s routes could change at any time, the API’s cannot (Versioning).
- Lists use cursors (
limit,cursor,meta.nextCursor) instead of pages: see Pagination. - Uploads and runs need an
Idempotency-Key, which makes retries safe: see Idempotency. - Which assessments a client sees depends on its acting role. Like the key, a User client sees only the questionnaires it uploaded itself, so it will not see what the key uploaded. Choose Reviewer if the script must see every questionnaire.
- Rate limits apply and are reported in
RateLimit-*headers: see Rate limits.