VetoVetoDocs
Hosted REST API

Validate & publish

The publish gate. Validate runs the SDK's pure config validator over your draft; publish validates, then activates the newest policy version and rebuilds the manifest.

Your draft config — merchant + receiving + catalog + the newest policy version — only goes live when you publish it. Publishing runs the same validator the CLI's config validate uses, then flips the newest policy version active in one transaction and invalidates the manifest cache.

Stage changes (catalog, receiving, a new policy version).
ValidatePOST /v1/validate to see findings without side effects.
PublishPOST /v1/publish validates again, then activates the newest policy version.

POST /v1/validate

Run the SDK's pure validateConfig() over the draft config assembled from current DB rows. No side effects — a dry run that returns reason-coded findings.

AuthAPI key · scope merchants:read
Querymerchant_id (optional)
200 — clean
{ "ok": true, "findings": [] }
200 — with findings
{
  "ok": false,
  "findings": [
    { "code": "RECEIVING_NO_RAIL_ENABLED", "human": "Configure at least one rail." }
  ]
}

ok is true only when findings is empty. The endpoint always returns 200 — the findings are the payload, not an HTTP error.

curl -X POST "https://api.veto-ai.com/v1/validate?merchant_id=mrch_01J…" \
  -H "Authorization: Bearer veto_test_8f2c…"

POST /v1/publish

The publish gate. (1) Validates the draft; if invalid, refuses with 422. (2) In one transaction, deactivates the current active policy and activates the newest version. (3) Invalidates the manifest cache so the next discovery serve rebuilds from the published inputs.

AuthAPI key · scope merchants:write

Response — 200

{ "published": true, "ok": true, "active_policy_version": 4 }

Response — 422 (validation failed)

{
  "published": false,
  "ok": false,
  "findings": [ /* … */ ],
  "reason_codes": ["CONFIG_INVALID"],
  "error_human": "Config did not pass validation; fix findings before publishing."
}

Status codes

StatusReason codeMeaning
200Published; newest policy version is now active.
404NOT_FOUNDMerchant not found in this project/mode.
422CONFIG_INVALIDDraft failed validation; findings say why.
publish
curl -X POST "https://api.veto-ai.com/v1/publish?merchant_id=mrch_01J…" \
  -H "Authorization: Bearer veto_test_8f2c…"

Idempotent flip

If the newest version is already active, publish is a no-op flip — it still re-validates and re-warms the manifest, returning the current active_policy_version.