Tracira

Any HTTP client

Tracira works with any tool that can make an HTTP POST request, including Zapier, Pipedream, custom scripts, or your own server.

Tracira works with any tool that can make an HTTP POST request: Zapier, Pipedream, custom scripts, or your own server. Here is the complete request format.

Get your webhook token

Open the Integrations tab in your workspace and copy your token from there.

Send the request

POST to https://tracira.com/api/logs with:

  • Header: Authorization: Bearer YOUR_TOKEN
  • Body: JSON with at minimum project and output

Use the verdict

Pass "sync": true to receive the evaluation result immediately in the response. Check status: pass means all rules passed, flagged means at least one rule triggered.

Send an output

curl -X POST https://tracira.com/api/logs \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "my-project",
    "output": "The AI-generated text.",
    "sync": true
  }'

Response

{
  "ok": true,
  "id": "b1c2d3e4-...",
  "status": "pass"
}

Logging a conversation

For a chatbot or any multi-turn thread, send one output per exchange and group the turns with sessionId - don't send the full messages array on every call:

{
  "project": "Customer Support",
  "input": "Hi, my order #8841 never arrived. Can you help?",
  "output": "Sorry to hear that! I've checked order #8841 and...",
  "sessionId": "thread_5f2a"
}
  • input is only the newest user message - the one this reply answers. Your call to your AI provider can still carry the full history; Tracira only needs the new turn.
  • sessionId is your conversation or thread ID, identical on every turn. Tracira stitches all outputs sharing it into one readable thread, nothing repeated. (conversationId, threadId, and chatId are accepted as aliases.)
  • Leave the system prompt out - it's configuration, not conversation. The best place for it is Tracira itself - see Hosted instructions.

Hosted instructions (self-improving prompts)

Tracira can host the instructions (system prompt) your AI runs with, versioned, with the people who review its output able to read, edit, and restore them in the dashboard. Fetch them at the start of every run instead of hardcoding the prompt:

curl -X POST https://tracira.com/api/instructions \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "Customer Support",
    "task": "Email reply",
    "default": "You write friendly, concise replies to customer emails..."
  }'
# -> { "content": "You write friendly...", "version": 3, "updatedAt": "..." }

The very first call saves default as version 1 and returns it; after that, the stored text always wins and default is ignored. Use content as your system message, and include the version when you submit the output so it links back to the exact instructions that produced it:

{
  "project": "Customer Support",
  "task": "Email reply",
  "input": "Where is my order?",
  "output": "It ships tomorrow...",
  "instructionsVersion": 3
}

To make the prompt self-improving, react to a changed decision: rewrite the current instructions with your own AI step so the reviewer's comment is followed from now on, then save the result as the new active version:

curl -X POST https://tracira.com/api/instructions/versions \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "Customer Support",
    "task": "Email reply",
    "content": "You write friendly, concise replies... Always sign off as The Support Team.",
    "teachComment": "Always sign off as The Support Team",
    "logId": "b1c2d3e4-..."
  }'
# -> { "version": 4 }

Tracira stores, versions, and serves the text - the rewriting stays in your automation, with your own AI step and keys. See the API reference for the full schemas.

Reviewers can also coach replies that already went out: pressing Teach the AI on a decided or passed output fires a taught webhook event. It carries the same fields as a changed decision (comment, output, instructionsVersion, ...) but nothing should be regenerated or resent - route it to the same instructions-rewrite step so the lesson applies from the next run onward.

Reviewing an action before it runs

When your AI decides to do something with side effects (issue a refund, delete a record, send an escalation), you can gate that action on human approval. Add an optional action object to the output. Tracira shows reviewers the plain-language summary, they approve or reject, and your automation runs the action only after approval (pair it with callbackUrl).

{
  "project": "Customer Support",
  "output": "I have prepared the refund and sent it for approval.",
  "action": {
    "name": "issue_refund",
    "summary": "Refund €49.00 to Alice Martin (order #8841)",
    "params": { "amount": 49.0, "currency": "EUR", "order": "8841" }
  },
  "callbackUrl": "https://hook.eu1.make.com/abc123"
}

Your automation supplies the summary - write it as a clear sentence, because reviewers read it verbatim to decide. Tracira never executes the action itself. Rules can also gate it: a data-field rule on action.params.amount can flag any refund over a threshold. Nothing else about your payload changes - action is entirely optional and additive.

Attaching files

Tracira can store images, audio, and PDFs alongside an output so reviewers see the source the AI worked from. How you attach depends on the file size.

The 4.5 MB request-body limit

The /api/logs request body is capped at 4.5 MB by our hosting platform. Because base64 inflates a file by about 33%, a base64-inline file effectively has to stay under ~3 MB. Larger files return 413 FUNCTION_PAYLOAD_TOO_LARGE. For anything bigger, use a URL or a presigned upload (below), where the file never travels in the request body.

Small files: URL or inline base64

{
  "project": "Invoice Review",
  "output": "...",
  "attachments": [
    { "source": "url", "url": "https://example.com/invoice.pdf" }
  ]
}

source: "url" (Tracira fetches it server-side, up to 32 MB) or source: "upload" with base64 data (kept under the 4.5 MB body cap).

Large files: direct upload (up to 32 MB)

Upload the file straight to Tracira's storage, then reference it by key. Three calls:

Create the upload

curl -X POST https://tracira.com/api/uploads \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "filename": "invoice.pdf" }'
# -> { "uploadUrl": "https://...", "key": "...", "contentType": "application/pdf" }

Upload the bytes

PUT the raw file to uploadUrl with the Content-Type from the response. These bytes go straight to storage, not through /api/logs, so they are not subject to the 4.5 MB cap:

curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: application/pdf" \
  --data-binary @invoice.pdf

Submit the output

Reference the upload by key. Nothing else is needed; Tracira links the file to this output:

curl -X POST https://tracira.com/api/logs \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "Invoice Review",
    "output": "The invoice looks valid.",
    "attachments": [{ "source": "uploaded", "key": "KEY_FROM_STEP_1" }]
  }'

Quota and cleanup

Each in-flight upload reserves space against your workspace storage quota (the sizeBytes you declare, or the per-file max if omitted), so pending uploads can never push you over your plan limit. The reservation is released when the upload is linked to an output, and any upload never referenced by an output is deleted automatically within 24h. Linked files count toward storage like any other attachment.

Tip

For Zapier or Pipedream: use their built-in HTTP/Webhook action, set Method to POST, add the Authorization header, and paste the JSON body. Then add a conditional step after it to branch on status. For files over ~3 MB, do the create-upload + PUT as two HTTP steps before the final POST.

On this page