v0.1 · Public Beta

Intaglio Documentation

Policy enforcement and tamper-proof audit trail for autonomous AI agents. Sub-millisecond APL evaluation. SHA-256 hash chain. Solana-anchored compliance records.

#Quick Start

Three API calls. No SDK required to start. Every action gets a SHA-256 chain link and an immutable outcome.

1
Get an API key
Create an account and copy your key from Dashboard → Settings → API Keys. Keys are prefixed itg_live_.
2
Register an agent
One agent = one identity. Each agent has exactly one active policy at a time.
3
Enforce every action
Wrap every agent action in POST /v1/enforce. Intaglio returns APPROVE, DENY, or REQUIRE_APPROVAL in under 1ms.
# 1. Register your agent
curl -X POST https://api.intaglio.tech/v1/agents \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"slug":"my-agent","display_name":"My First Agent","policy":"conservative-v1"}'

# 2. Enforce an action
curl -X POST https://api.intaglio.tech/v1/enforce \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"agent":"my-agent","action":{"type":"TRANSFER","amount_usd":100}}'

# 3. Pull the audit trail
curl https://api.intaglio.tech/v1/audit?agent=my-agent \
  -H "Authorization: Bearer YOUR_API_KEY"

30-second integration. Drop in three lines of code and every agent decision gets a tamper-proof audit record — no infrastructure to run, no schema to deploy.


#Authentication

All requests require a Bearer token in the Authorization header.

Key typePrefixUse
Live keyitg_live_Production enforcement. Records anchored to Solana mainnet.
Test keyitg_test_Dry-run mode. No Solana anchoring, no billing. Full audit trail in Supabase.
🔒

API keys are shown once on creation. Store them in environment variables — never commit them to source control.


#Enforce an Action

The core primitive. Every AI agent action passes through this endpoint before execution. Intaglio evaluates the action against the agent's policy in under 1ms and returns a signed, chained decision record.

Request

curl -X POST https://api.intaglio.tech/v1/enforce \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": "my-defi-agent",
    "action": {
      "type": "TRANSFER",
      "amount_usd": 4200,
      "recipient": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "chain": "ethereum"
    }
  }'

Response — DENY

Response 200 · outcome: DENY
{
  "outcome": "DENY",
  "reason": "EXCEEDS_DAILY_LIMIT",
  "policy_version": "conservative-v1",
  "sha256": "sha256:a3f9c1e74d2b8f65c9e0123456789abc",
  "prev_hash": "sha256:f1e2d3c4b5a6978869504132",
  "enforcement_ms": 0.87,
  "anchored_to": null,
  "anchor_pending": true,
  "timestamp": "2026-05-07T11:42:03.221Z"
}

Response — APPROVE

Response 200 · outcome: APPROVE
{
  "outcome": "APPROVE",
  "policy_version": "conservative-v1",
  "sha256": "sha256:b7c4d9f0e1a23456789abcdef01234567",
  "prev_hash": "sha256:a3f9c1e74d2b8f65c9e0123456789abc",
  "enforcement_ms": 0.74,
  "anchored_to": "solana:mainnet:tx/4vhKmNpQ...",
  "timestamp": "2026-05-07T11:43:10.004Z"
}

Response — REQUIRE_APPROVAL

Response 200 · outcome: REQUIRE_APPROVAL
{
  "outcome": "REQUIRE_APPROVAL",
  "reason": "AMOUNT_EXCEEDS_AUTO_APPROVE_THRESHOLD",
  "approval_request_id": "apr_01HX9ZKCV3NFGPQ4T7Y8M2W6E",
  "policy_version": "conservative-v1",
  "sha256": "sha256:c8d5e0f1a23456789abcdef012345678",
  "enforcement_ms": 0.91,
  "webhook_fired": true,
  "timestamp": "2026-05-07T11:44:22.887Z"
}

All three outcomes return sha256 and prev_hash, forming an unbreakable chain. The anchored_to field is populated asynchronously after Solana confirmation (typically 2–4 seconds).


#Outcomes

Every enforcement returns exactly one of three outcomes.

APPROVE
Action permitted
Within all policy limits. Execute immediately. Record anchored to Solana.
DENY
Action blocked
Violates a hard limit or compliance rule. Do not execute. Record includes deny reason code.
REQUIRE_APPROVAL
Human review
Exceeds auto-approve threshold. Hold and wait. Webhook fires. Expires after 1 hour.

Deny reason codes

Reason codeDescription
EXCEEDS_PER_TRANSACTION_LIMITAction amount exceeds the policy per-transaction ceiling
EXCEEDS_DAILY_LIMITCumulative spend for today would exceed the daily cap
EXCEEDS_HOURLY_LIMITHourly spend window would be exceeded
OFAC_SANCTIONS_MATCHRecipient address matched OFAC SDN list
UNSUPPORTED_CURRENCYCurrency not in policy scope
UNSUPPORTED_RAILPayment rail not in policy scope
POLICY_EXPIREDAgent's policy has passed its expiry date
AGENT_SUSPENDEDAgent has been manually suspended by operator

#Policy Language (APL)

Agent Policy Language is a deterministic, human-readable DSL for defining spending limits, approval thresholds, and compliance obligations. Policies are version-controlled and immutable once deployed. Any change creates a new version — the old record is preserved.

defi-agent.apl
policy defi-agent-policy v1.2.0
agent  my-defi-agent
operator acme-corp

# Which payment rails this policy governs
scope {
  rails      [x402 evm solana]
  currencies [USDC USDT SOL ETH]
}

# Hard spending limits — never overrideable
limit {
  per_transaction { value 1000  currency USDC }
  per_hour        { value 2000  currency USDC }
  per_day         { value 10000 currency USDC }
}

# Amounts above this threshold require human sign-off
require {
  human_approval_above { value 500 currency USDC }
}

# Compliance obligations
obligation {
  ofac_check  enabled
  log_to      solana:mainnet
  retention   7y
  notify      webhook:https://yourapp.com/hooks/intaglio
}
BlockRequiredDescription
policyYesPolicy name, version, and identity binding. Version uses semver.
scopeYesWhich rails and currencies this policy governs. Actions on unlisted rails are denied.
limitYesHard spending limits. Per-transaction, per-hour, per-day. Cannot be overridden at runtime.
requireNoConditions that trigger REQUIRE_APPROVAL instead of DENY (e.g. large transfers).
obligationNoCompliance obligations: OFAC screening, Solana logging, retention period, webhook URL.
📄

Open standard. The intaglio.policy.json schema is published under CC-BY-4.0. Any tool can parse, validate, or render APL files — no vendor lock-in. View schema →


#Hash Chain

Every enforcement record contains two hashes: its own sha256 (over the record payload) and prev_hash (the hash of the immediately preceding record for the same agent). This forms a tamper-evident chain — modifying any record breaks all subsequent links.

Record #1
TRANSFER $50 USDC
APPROVE
sha256: sha256:000...genesis
prev:
Record #2
TRANSFER $200 USDC
APPROVE
sha256: sha256:aaa111...
prev: sha256:000...
Record #3
TRANSFER $9,000 USDC
DENY
sha256: sha256:bbb222...
prev: sha256:aaa111...
curl https://api.intaglio.tech/v1/audit?agent=my-agent&verify=true \
  -H "Authorization: Bearer YOUR_API_KEY"
# Returns: { "chain_valid": true, "records_verified": 147, "broken_at": null }

#Solana Anchoring

Every APPROVE record is anchored to Solana mainnet via the Memo program. The SHA-256 hash is written on-chain within 2–4 seconds of enforcement. This makes the audit trail independently verifiable — you don't need to trust Intaglio's database.

FieldValue
anchored_tosolana:mainnet:tx/4vhKmNpQ... (populated async)
anchor_pendingtrue while Solana confirmation is in flight
Memo programMemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr
Memo contentintaglio:v1:{sha256_hash}
Clustermainnet-beta (test keys use devnet)
⛓️

Independent verification: any Solana explorer (Solscan, SolanaFM) can confirm a record exists. No Intaglio account required. This is what "blockchain-anchored audit trail" actually means.


#Webhooks

When an action returns REQUIRE_APPROVAL, Intaglio fires a webhook to the URL defined in your policy's obligation.notify field. Your system has 1 hour to approve or deny before the request expires.

Webhook payload

POST → your webhook URL
// POST to your webhook URL when outcome = REQUIRE_APPROVAL
{
  "event": "approval.requested",
  "approval_request_id": "apr_01HX9ZKCV3NFGPQ4T7Y8M2W6E",
  "agent": "my-defi-agent",
  "action": {
    "type": "TRANSFER",
    "amount_usd": 4200,
    "recipient": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
  },
  "policy_version": "conservative-v1",
  "sha256": "sha256:c8d5e0f1a23456789abcdef012345678",
  "created_at": "2026-05-07T11:44:22.887Z",
  "expires_at": "2026-05-07T12:44:22.887Z"
}

Responding to approvals

// Approve the pending action
curl -X POST https://api.intaglio.tech/v1/approvals/apr_01HX9ZKCV3NFGPQ4T7Y8M2W6E/approve \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"approved_by":"alice@acme.com","note":"Verified counterparty"}'

// Deny it
curl -X POST https://api.intaglio.tech/v1/approvals/apr_01HX9ZKCV3NFGPQ4T7Y8M2W6E/deny \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"denied_by":"alice@acme.com","reason":"Unrecognised recipient"}'

Approvals and denials are themselves enforcement records — they get their own SHA-256 hash and are anchored to Solana. The full chain is: enforce → require_approval → approve/deny.


#Audit Trail

Pull the full history for any agent. Records are append-only — Intaglio's database enforces Row Level Security with no UPDATE or DELETE permissions on audit records.

# Full audit trail for an agent
curl "https://api.intaglio.tech/v1/audit?agent=my-defi-agent&limit=50" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Filter by outcome
curl "https://api.intaglio.tech/v1/audit?agent=my-defi-agent&outcome=DENY" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Export PDF compliance report
curl "https://api.intaglio.tech/v1/audit/export?agent=my-defi-agent&format=pdf" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  --output audit-report.pdf
ParameterTypeDescription
agentstringAgent slug. Required.
limitintegerRecords per page. Default 50, max 500.
cursorstringPagination cursor from previous response.
outcomestringFilter by APPROVE | DENY | REQUIRE_APPROVAL.
sinceISO 8601Return records after this timestamp.
untilISO 8601Return records before this timestamp.
verifybooleanIf true, verify the chain integrity before returning.

#Compliance

Intaglio is designed from the ground up for regulated environments. The audit trail is built to satisfy MiCA Article 68 (record-keeping obligations for crypto-asset service providers) and the emerging EU AI Act requirements for high-risk AI system logging.

RequirementHow Intaglio addresses it
MiCA Art. 68 — Record keepingAppend-only audit records, 7-year retention, PDF export for regulators
OFAC SDN screeningBuilt into APL obligation block. Checks recipient addresses on every TRANSFER action.
ImmutabilitySHA-256 hash chain + Solana anchoring. Tampering breaks the chain and is detectable by any third party.
Audit exportPDF reports generated on demand. Machine-readable JSON also available.
Data residencySupabase project hosted in EU-West (Frankfurt). Records never leave EU by default.
EU AI Act Art. 12 — LoggingAutonomous decision log with confidence score, policy version, timestamp, and actor identity.

Verifiable without Intaglio. A compliance auditor can independently verify any record using only the SHA-256 hash and a Solana block explorer — no access to Intaglio's systems required.


#Errors

All errors return a JSON body with error.code and error.message.

HTTP statusCodeMeaning
400INVALID_REQUESTMissing required field or malformed JSON.
401UNAUTHORIZEDMissing or invalid API key.
403FORBIDDENKey doesn't have access to this agent.
404AGENT_NOT_FOUNDNo agent with this slug for your account.
409POLICY_CONFLICTAgent already has an active policy with this version.
422POLICY_PARSE_ERRORAPL syntax error. Response includes line/column.
429RATE_LIMITEDExceeded 10,000 enforcements/min. Retry-After header set.
500INTERNAL_ERRORIntaglio fault. Retry safe — idempotent by request ID.
Error response shape
{
  "error": {
    "code": "AGENT_NOT_FOUND",
    "message": "No agent with slug 'my-missing-agent' found for this account.",
    "docs": "https://intaglio.tech/docs#errors"
  }
}

Questions not covered here? Email the team or open an issue on GitHub.