Skip to content
Vecaria
Go Pro

Developer API

Vecaria exposes an HTTP API for batch jobs and workflows. Authenticated endpoints use the session cookie (credentials: "include"); webhook trigger endpoints use a secret and do not require login. A machine-readable OpenAPI 3.1 spec is available at /openapi.json.

  • Base URL: https://vecaria.com
  • Response envelope: { "ok": true, "data": … } or { "ok": false, "error": { "code": "…", "message": "…" } }
  • All limits, costs and trigger switches are configured in the admin (batch_configs / workflow_configs); the API reads the effective values.

Official zero-dependency clients wrap upload → job → download and the MCP endpoint:

  • JavaScriptsdk/index.mjs (vecaria-sdk) + CLI sdk/cli.mjs
    import { VecariaClient } from "vecaria-sdk";
    const cf = new VecariaClient({ token: process.env.VECARIA_TOKEN });
    const { fileId, url } = await cf.convert("drawing.dxf", bytes, { operation: "dxf.to.svg" });
  • Pythonpip install ./sdk/python (vecaria), Python 3.9+ stdlib only
    from vecaria import VecariaClient
    cf = VecariaClient(token=os.environ["VECARIA_TOKEN"])
    out = cf.convert("drawing.dxf", open("drawing.dxf", "rb").read(), operation="dxf.to.svg")
    CLI: vecaria convert drawing.dxf --op dxf.to.svg --out out.svg

Both also expose mcp(method, params) for the Model Context Protocol endpoint below.

POST /api/mcp speaks MCP over Streamable HTTP (JSON-RPC). Anonymous callers can use read-only tools (list_tools, ping); authenticated callers additionally get list_batches, list_workflows, and write tools (create_batch, run_workflow) when the token carries the mcp:write scope.

{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }

POST /api/batch/estimate · login required

{ "fileCount": 10 }

Returns { credits, baseCredits, perFileCredits, maxFiles }.

POST /api/batch · login required

{ "type": "pdf.compress", "fileIds": ["<fileId>", ""], "params": {}, "name": "Archive", "engine": "server" }
  • fileIds are ids confirmed through the upload endpoints (UPLOADED).
  • Bounded by batch.max_files_* / batch.max_size_mb_*; charged as base + per_file × N.
  • Returns { batchId, credits }.
  • GET /api/batch/:id{ batch, files[] } (per-file status/errorCode/outFileId)
  • GET /api/batch/:id/events → SSE { total, done, failed, status } (ends automatically on terminal state)
  • POST /api/batch/:id/cancel
  • POST /api/batch/:id/retry (failed items only)
  • GET /api/batch/:id/zip (streamed STORE zip)
  1. POST /api/files/presign-upload { filename, mime, size, jobType, createJob:false }{ fileId, uploadUrl }
  2. PUT <uploadUrl> (body is the file)
  3. POST /api/files/confirm { fileId }

POST /api/files/import-url { url, filename?, mime?, jobType?, createJob? } — fetches a remote http(s) file (SSRF-guarded, size-capped) into R2 and returns { fileId } for batch/workflow use.

POST /api/workflows/validate { graphJson }{ issues[], ok } (structure / cycles / step count / IO compatibility).

  • POST /api/workflows { name, graphJson, paramsJson? }
  • GET /api/workflows, PUT /api/workflows/:id, DELETE /api/workflows/:id
  • POST /api/workflows/:id/estimate{ credits, steps, maxSteps }
  • POST /api/workflows/:id/run { fileIds[] }{ runId, credits }
  • GET /api/workflows/runs/:runId{ run, steps[] } (step-by-step timeline)
  • POST /api/workflows/runs/:runId/retry
{
"nodes": [
{ "id": "s", "type": "source.upload", "data": { "type": "source.upload", "io": { "produces": ["pdf"] } } },
{ "id": "c", "type": "op.pdf.compress", "data": { "type": "op.pdf.compress", "params": { "level": 5 }, "io": { "accepts": ["pdf"], "produces": ["pdf"] } } },
{ "id": "z", "type": "sink.zip", "data": { "type": "sink.zip", "params": { "name": "out" } } }
],
"edges": [ { "source": "s", "target": "c" }, { "source": "c", "target": "z" } ]
}

Node kinds: trigger.* (manual/webhook/schedule), source.upload, op.*, logic.filter|merge, sink.download|zip|rename.

  • GET /api/workflows/:id/triggers
  • PUT /api/workflows/:id/triggers { type: "webhook"|"schedule"|"watch", config }{ id, secret }
  • DELETE /api/workflows/:id/triggers/:triggerId

Prefer HMAC signing; legacy secret in the body is still accepted.

X-Vecaria-Timestamp: <unix seconds>
X-Vecaria-Signature: sha256=<hmac_sha256_hex(secret, `${timestamp}.${rawBody}`)>

POST /api/workflows/:id/hook with the JSON body { "fileIds": ["<fileId>"] } (signatures older than 300s are rejected to prevent replay).

Legacy form (no signature headers):

{ "secret": "<webhook secret>", "fileIds": ["<fileId>"] }
  • schedule: config.cron (UTC 5-field cron; prefer multiples of 5 for the minute, dispatched by the system 5-minute cron).
  • watch: config.suffix (e.g. .dxf) / config.prefix; runs automatically after a matching user upload is confirmed.
  • Outbound webhook: paramsJson.notifyUrl; on run completion POST { runId, status, fileIds|error }. If paramsJson.notifySecret is set (≥8 chars), the request also carries X-Vecaria-Timestamp / X-Vecaria-Signature (same HMAC scheme as above).
  • Email: enable workflow.notify_email_enabled in the admin (requires RESEND_API_KEY).
  • Add a logic.approval node to the graph (params.timeoutSeconds).
  • Approve: POST /api/workflows/runs/:runId/approve { "decision": "approved" | "rejected", "note": "…" }.
  • Use an op.workflow node (params.workflowId) to run another workflow within the same run; nesting is limited to 3 levels.
  • Endpoint: POST /api/mcp (JSON-RPC 2.0, Streamable HTTP).
  • Methods: initialize, tools/list, tools/call.
  • Read-only tools: list_tools, ping (no auth).
  • Token tools (Authorization: Bearer vk_…): list_batches, list_workflows; write tools (create_batch, run_workflow) require a token with the mcp:write scope.
  • Example: {"jsonrpc":"2.0","id":1,"method":"tools/list"}.

Processing runs in the browser first; cloud processing is enabled only when uploads/limits allow it, and artifacts are cleaned up according to the retention policy.