Skip to content
Docs

    Workspace API reference

    7 min read · Updated View as Markdown

    These are the endpoints of your workspace that accept API keys. Everything else in the workspace serves the browser. There is no public API yet for querying telemetry or for managing organizations and workspaces.

    Conventions

    ConventionDetail
    Base URLYour workspace's address, such as https://production-a7k3p2q9.app.tracix.io. The examples call it TRACIX_URL
    AuthenticationX-API-Key: txk_... on every request, over HTTPS
    BodiesJSON, with Content-Type: application/json
    ErrorsA status code and a JSON body with an error message
    TimesUTC, in ISO 8601
    StatusMeaning
    401The key is missing, unknown, expired or revoked
    403The key doesn't carry the permission the endpoint needs

    Detection content

    These endpoints take a CI key. They back the tracix-detections CLI; see Monitors, dashboards and detections as code for the repository format.

    Validate, plan or apply

    POST /api/security/detections takes the files of a detection repository at one commit, or a reference the workspace fetches itself, and validates, plans or applies them.

    FieldTypeDescription
    actionstringRequired. validate, plan or apply
    filesobjectThe repository's files as {"path": "content"}. Send files or archiveRef, not both
    revisionstringRequired with files: the commit the files were taken at, up to 128 characters
    subdirstringThe folder that holds the detections, when it isn't the repository root
    archiveRefobject{"credentialId", "repo", "ref", "subdir"}: the workspace fetches this commit from GitHub or GitLab with a credential stored in the workspace. subdir is optional
    packagestringRefuse the request unless the manifest publishes this package
    partialbooleanvalidate only: the files are one batch of a larger repository
    planHashstringRequired for apply: the planHash of the plan you reviewed
    replacebooleanapply only: confirm the plan's conflicts, replacing the rules they name

    validate and plan need security.read; apply needs security.manage. Request bodies are limited to 10 MB: for a larger repository, send archiveRef.

    bash
    curl -fsS -X POST "$TRACIX_URL/api/security/detections" \
    -H "X-API-Key: $TRACIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d @request.json
    request.json
    {
      "action": "plan",
      "revision": "4f2c9e1",
      "files": {
        "tracix-detections.yaml": "package: acme-soc\nprune: true\n",
        "lists/service-accounts.yaml": "name: service-accounts\nitems:\n  - svc_backup\n"
      }
    }

    Responses

    ActionStatusBody
    validate200package, revision, valid, summary (counts of files, rules, lists, YARA rulesets, disabled rules, errors, warnings and fixture results), diagnostics, files, fixtures, ignored and source
    plan200Everything validate returns, plus planHash (null when the plan can't be applied), blocking, planWarnings, counts, resources (one row per object, with its action: create, update, delete, unchanged or conflict) and hiddenResources
    apply200applied: true, package, revision, planHash, counts (created, updated, deleted, unchanged, replaced), results, postApply and source
    apply202More than 200 writes run in the background: {"job": {"jobId", "status", "total"}, "source"}. Follow the job with the next endpoint

    valid is false when a file doesn't compile or a fixture fails. source says where the files came from: {"kind": "files"}, or the code host, repository and commit for archiveRef.

    Errors

    StatusWhen
    400The body isn't valid JSON, an unknown action, partial outside validate, a missing or malformed planHash, a package that doesn't match the manifest, or a plan that compile errors block
    404archiveRef: the credential, the repository or the commit can't be found or read
    409The content or the workspace changed since the plan, so plan again; the plan has conflicts you haven't confirmed; or another apply is running
    413The body is larger than 10 MB, or the repository exceeds 5,000 detection files or 50 MB
    502The code host refused the request, or the change wasn't accepted. Try again

    Follow a background apply

    GET /api/security/detections?job=<jobId> returns the progress of an apply that runs in the background. It needs security.read.

    The response is {"job": {...}} with jobId, package, revision, planHash, status (running, succeeded, failed or interrupted), total, done, counts, results, startedAt, updatedAt and, once finished, finishedAt. A job that failed or was interrupted also has an error, and a failed one the failedResource it stopped at. It answers 400 without a valid job ID and 404 for an unknown one.

    Download the CLI

    GET /api/security/detections/cli returns the tracix-detections CLI that matches this workspace, as tracix-detections.mjs. It needs security.read. The X-Tracix-Cli-Sha256 response header carries the file's SHA-256, so a pipeline can check it before running it.

    bash
    curl -fsS -H "X-API-Key: $TRACIX_API_KEY" -D cli.headers \
    "$TRACIX_URL/api/security/detections/cli" -o tracix-detections.mjs

    Export detection content

    GET /api/security/detections/export returns detection content as repository files. It needs security.read, and a key sees every rule and list.

    QueryDescription
    packageRequired. The package to export, or for source=ui, the package name for the new files
    sourcepackage (the default) exports the rules and lists a package publishes. ui exports rules authored in the UI as a new repository
    ids, tag, techniquesource=ui only: which rules. Repeat a parameter or separate values with commas; ids takes up to 500
    packsource=ui: include adds rules installed from the Sigma pack to a tag or technique selection
    listssource=ui: include also writes the value lists the rules use
    formatzip returns a ZIP archive instead of JSON

    A package export returns package, revision, files ({"path": "content"}), resources (each with exact: true when compiling the file reproduces what the workspace runs), summary and notes. Fixtures aren't stored in the workspace, so they aren't exported. It answers 404 when nothing is published under the package; a source=ui export answers 404 when no rules match and 422 when none of them can be exported.

    External alerts

    These endpoints take an API key of the ingest type, with any write: permission. Alerts they receive open and resolve alert episodes alongside your own monitors'.

    Receive Alertmanager alerts

    POST /api/ingest/alertmanager takes the payload Prometheus Alertmanager sends to a webhook receiver. Send the API key in the X-API-Key header.

    From the Alertmanager alertBecomes
    statusfiring opens or re-asserts an episode; resolved recovers it
    fingerprintThe identity of the alert stream
    The first of the labels instance, host, hostname, service, pod, alertnameThe entity
    The severity labelcritical for critical, page, p1, error or fatal; warning for warning, warn, p2 or p3; info otherwise
    The summary or description annotationThe reason

    The response is {"ok": true, "opened", "reasserted", "resolved", "ignored"}.

    Send alert events

    POST /api/ingest/events takes events from your own scripts, relays and third-party systems.

    FieldTypeDescription
    eventsarrayRequired. Up to 100 events per request; more are ignored
    events[].dedupeKeystringRequired. Identifies the alert stream: events with the same source and dedupeKey update one episode
    events[].statusstringRequired. firing or resolved
    events[].entitystringRequired. What the alert is about, such as a host or service name
    events[].sourcestringUp to 32 letters, digits, _ or -. Defaults to webhook
    events[].titlestringDefaults to <source>: <entity>
    events[].reasonstringDefaults to external alert
    events[].severitystringMapped the same way as Alertmanager's severity label
    events[].labelsobjectUp to 10 string labels

    Events missing a required field are dropped. Long values are cut to fit: 256 characters for dedupeKey and entity, 300 for title and 1,000 for reason.

    bash
    curl -fsS -X POST "$TRACIX_URL/api/ingest/events" \
    -H "X-API-Key: $TRACIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"events": [{"dedupeKey": "backup-nightly", "status": "firing", "entity": "db-01", "source": "backup", "severity": "warning", "reason": "Nightly backup did not finish"}]}'
    Response
    { "ok": true, "received": 1, "dropped": 0, "opened": 1, "reasserted": 0, "resolved": 0, "ignored": 0 }

    It answers 400 when the body has no events array or no valid event.

    Next steps