API reference

    This is the public API: calling a tool over REST or MCP, reading your workspace over the workspace MCP, and the webhooks you can be sent. It's drawn from the same description the API serves at /api/v1/openapi.json, so the two always agree. A tool's exact search schema is its own, built from what its owner lets callers filter, exclude and sort: read it from the tool's schema endpoint.

    Base URL https://cloudcrane.in/api. Every call sends its key as Authorization: Bearer <key>: a tool key (cc_live_…) for a tool, a build key (cc_build_…) for the workspace MCP. Errors come back as { "error": "…" }, with a detail when a request didn't match.

    The same description, for code generators and agents: https://cloudcrane.in/api/v1/openapi.json.

    get/v1/tools/{name}/schematool key

    What the tool is and what it takes

    The tool's name and description for an agent, the release it serves, how that release measured on its answer key (when it has one), and the JSON Schema of the search request: which filters, exclusions and sorts this tool allows. Doesn't count towards the key's quota.

    Parameters

    name*stringpath. The tool's name, as its owner set it.

    Responses

    • 200The tool · ToolDescription
    • 401No key, or a key that is revoked or expired. Send it as Authorization: Bearer <key>. · Error
    • 403A browser origin the key doesn't allow. Call from your server, or add the origin to the key. · Error
    • 404No tool with that name for this key. · Error
    • 429The key's rate limit or monthly quota. Retry-After says when to try again after a rate limit. · Error
    • 503The tool is paused by its owner, or has no published data yet. · Error
    post/v1/tools/{name}/searchtool key

    Search the tool's records

    Words, a record to find others like, filters, safety exclusions and sorting, as the tool's schema allows. Exclusions are enforced by the server: a record comes back only if it is known not to have an excluded value, so an unknown value is never treated as safe. Exclusions pinned to the key are always applied as well; a request can only narrow them.

    Parameters

    name*stringpath. The tool's name, as its owner set it.

    Body

    querystringWords to search for.up to 200 chars
    similar_tostring (uuid)A record's id; returns records like it instead. Not with query.
    filtersobjectOnly records matching every given filter.
    excludeobjectSafety field → values to leave out. A record is returned only if it is known not to have any of them.
    sortobject[]
    ↳ field*string
    ↳ direction"asc" | "desc"
    limitintegerResults per page, up to the tool's maximum.min 1
    cursorstringnext_cursor from the previous page, with the same other parameters.
    include_receiptsbooleandefault true

    Responses

    • 200A page of results · SearchResult
    • 400The request doesn't match this tool's schema; detail says where. · Error
    • 401No key, or a key that is revoked or expired. Send it as Authorization: Bearer <key>. · Error
    • 403A browser origin the key doesn't allow. Call from your server, or add the origin to the key. · Error
    • 404No tool with that name for this key. · Error
    • 429The key's rate limit or monthly quota. Retry-After says when to try again after a rate limit. · Error
    • 503The tool is paused by its owner, or has no published data yet. · Error
    post/v1/tools/{name}/valuestool key

    Look up value set entries to filter or exclude by

    For a field choosing from a large value set: entries matching some words, by name, synonym or code, so their codes can go in filters and exclusions.

    Parameters

    name*stringpath. The tool's name, as its owner set it.

    Body

    field*stringA value set field the tool lets you filter or exclude by.
    query*stringup to 200 chars
    limitintegermin 1, max 25, default 10

    Responses

    • 200Matching entries
    • 400The request doesn't match; detail says where. · Error
    • 401No key, or a key that is revoked or expired. Send it as Authorization: Bearer <key>. · Error
    • 403A browser origin the key doesn't allow. Call from your server, or add the origin to the key. · Error
    • 404No tool with that name for this key. · Error
    • 429The key's rate limit or monthly quota. Retry-After says when to try again after a rate limit. · Error
    • 503The tool is paused by its owner, or has no published data yet. · Error
    get/v1/tools/{name}/items/{recordId}tool key

    One record by id

    A record a search returned, under the same safety exclusions the key applies. One the key's exclusions leave out looks the same as one that doesn't exist.

    Parameters

    name*stringpath. The tool's name, as its owner set it.
    recordId*string (uuid)path.
    include_receiptsbooleanquery.default true

    Responses

    • 200The record · Result
    • 400The id isn't valid. · Error
    • 401No key, or a key that is revoked or expired. Send it as Authorization: Bearer <key>. · Error
    • 403A browser origin the key doesn't allow. Call from your server, or add the origin to the key. · Error
    • 404No tool with that name for this key. · Error
    • 429The key's rate limit or monthly quota. Retry-After says when to try again after a rate limit. · Error
    • 503The tool is paused by its owner, or has no published data yet. · Error
    post/mcp/{name}tool key

    The tool over MCP

    JSON-RPC over Streamable HTTP, with the tool key as a bearer token. tools/list offers search_<name> (the same request as REST search), get_<name>, and find_values when the tool has value set fields. Answers go through the same code as REST, so validation, the safety guarantee and logging are identical. GET and DELETE return 405: there are no sessions.

    Parameters

    name*stringpath. The tool's name, as its owner set it.

    Body: A JSON-RPC 2.0 request, or a batch.

    Responses

    • 200The JSON-RPC response.
    • 401No key, or a key that is revoked or expired. Send it as Authorization: Bearer <key>. · Error
    • 403A browser origin the key doesn't allow. Call from your server, or add the origin to the key. · Error
    • 404No tool with that name for this key. · Error
    • 429The key's rate limit or monthly quota. Retry-After says when to try again after a rate limit. · Error
    • 503The tool is paused by its owner, or has no published data yet. · Error
    post/build/mcpbuild key

    Read, and build in, the workspace you're building

    For your own agent while you build: with a build key (cc_build_…) as a bearer token, it can list datasets and their columns, contracts, readiness, the review queue, receipts, value sets and runs. A key made to build can also create datasets, value sets and fields, edit fields, start runs, and publish when the accuracy gate passes by itself, through the dashboard's checks. Resolving review items, editing stored values, withholding, deleting and publishing past the gate stay with a person.

    Body: A JSON-RPC 2.0 request, or a batch.

    Responses

    • 200The JSON-RPC response.
    • 401No build key, or one that is revoked or expired. · Error
    • 403Called from a browser: a build key opens the whole workspace, so it only works from a server or an agent's runtime. · Error
    • 429The build key's rate limit or monthly quota. Retry-After says when to try again after a rate limit. · Error

    A result

    What each search result, and a single record, looks like.

    Result

    id*string
    fields*objectThe fields the tool returns, typed: a number is a number.
    origin*object
    ↳ kind"imported" | "generated"
    ↳ modelstringFor a generated record, the model that made it.
    unknown_safety_fieldsstring[]Safety fields nobody has decided on this record.
    receiptsobject

    Webhooks

    A POST to your own address when something happens. Every delivery carries the event in CloudCrane-Event, its id in CloudCrane-Delivery (the same on every retry, so you can ignore repeats) and a signature in CloudCrane-Signature. Check the signature before trusting a delivery:

    import { createHmac, timingSafeEqual } from "node:crypto";
    
    // header: the CloudCrane-Signature header; body: the raw request body, as received.
    export function verify(secret, body, header) {
      const parts = Object.fromEntries(header.split(",").map((p) => p.trim().split("=")));
      const t = Number(parts.t);
      if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > 300) return false;
      const expected = createHmac("sha256", secret).update(`${t}.${body}`).digest();
      const given = Buffer.from(parts.v1 ?? "", "hex");
      return given.length === expected.length && timingSafeEqual(given, expected);
    }

    release.readyA new release finished building

    data

    dataset_idstring
    release_idstring
    releaseintegerThe release's number.

    release.heldA tool's scenarios held a release back

    data

    tool_idstring
    toolstring
    releaseinteger
    failedobject[]
    ↳ scenariostring
    ↳ problemsstring[]

    drift.alertA sync found drift and is waiting for a person

    data

    dataset_idstring
    sync_idstring
    alertsobject[]
    ↳ fieldstring
    ↳ kindstring
    ↳ valuestring | null
    ↳ severitystring
    ↳ messagestring

    review.openedA run left decisions for a person

    data

    run_idstring
    dataset_idstring
    contract_idstring
    countintegerHow many decisions it left.

    tool.failingA fifth or more of a tool's calls failed over 15 minutes; at most once an hour per tool

    data

    tool_idstring
    toolstring
    callsinteger
    errorsinteger
    window_minutesinteger
    dedupe_keystringThe same for every alert about the same cause.

    accuracy.droppedMeasuring the saved fields found a safety value less often than in the last release; once a day per drop

    data

    dataset_idstring
    datasetstring
    evaluation_idstring
    regressionsobject[]
    ↳ fieldstring
    ↳ valuestring
    ↳ beforeobject
    ↳ afterobject
    dedupe_keystring

    credits.lowA fifth of the starter credits left, and again when none are

    data

    creditsinteger
    usedinteger
    leftinteger

    pingA test delivery, sent from the webhook's settings

    data

    messagestring