Features Solutions Technology Tokenomics Docs About Launch App
Docs / API Reference / REST API

REST API Reference

Everything TAG IT exposes over HTTP today. Every endpoint listed without a Planned marker is live and was verified by direct request on 26 July 2026 — you can call it right now, and most of it needs no key at all.

Testnet — not production

All contracts run on Base Sepolia testnet (chain ID 84532) and are unaudited. Verification results are suitable for integration and evaluation. Do not use them as the sole basis for a custody, payment or settlement decision.

What exists today

TAG IT has two HTTP hosts and one on-chain path. There is no single /v1 base URL — endpoints are grouped by the host that serves them.

Endpoint Auth Callable by
GET api.tagit.network/health None Anyone
POST api.tagit.network/verify x402 payment Agents with USDC on Base
GET verify.tagit.network/api/verify SUN cryptogram A device that physically tapped the chip
GET verify.tagit.network/api/dpp/… SUN cryptogram A device that physically tapped the chip
Direct contract read (viem / ethers / cast) None Anyone, including AI agents
Attestation vs assertion

Verification has two halves with deliberately opposite access rules. Attestation — proving a specific physical chip was present — requires a real NFC tap and a SUN cryptogram, and is intentionally not reachable without one. Assertion — reading the resulting on-chain state — is open to everyone, with no key, wallet or signup. If you are building an agent, the assertion half is what you want.

Reading state directly from the chain

The most reliable integration path requires no TAG IT credential at all: read the TAGITCore contract yourself over any public Base Sepolia RPC. You do not have to trust our API — you can re-derive every verdict independently.

ContractAddress
TAGITCore 0x3aDc7EFDb58Ae85483eFf5D4966D916185f31d1D

See Contract Addresses for the full deployment list.

// npm install viem
import { createPublicClient, http } from 'viem';
import { baseSepolia } from 'viem/chains';

const client = createPublicClient({ chain: baseSepolia, transport: http() });

const TAGITCoreABI = [{
  name: 'getAsset', type: 'function', stateMutability: 'view',
  inputs: [{ name: 'tokenId', type: 'uint256' }],
  outputs: [
    { name: 'assetOwner', type: 'address' },
    { name: 'timestamp',  type: 'uint64'  },
    { name: 'state',      type: 'uint8'   },
    { name: 'flags',      type: 'uint8'   },
    { name: 'reserved',   type: 'uint16'  },
  ],
}];

const [owner, timestamp, state] = await client.readContract({
  address: '0x3aDc7EFDb58Ae85483eFf5D4966D916185f31d1D',
  abi: TAGITCoreABI,
  functionName: 'getAsset',
  args: [50n],
});

console.log({ owner, timestamp, state });
// → { owner: '0x458B4d0c3a55006965Fd13D6af7B8509De51Cb3D',
//     timestamp: 1784246184n, state: 4 }   // 4 = CLAIMED

Lifecycle states

The state field is an integer from the asset lifecycle state machine:

CodeStateMeaning
0NONEToken does not exist
1MINTEDDigital twin created, no chip bound yet
2BOUNDNFC chip cryptographically bound
3ACTIVATEDQA passed, ready for distribution
4CLAIMEDOwned by an end consumer
5FLAGGEDReported lost, stolen or recalled
6RECYCLEDEnd of life, terminal

GET /health

Gateway liveness check. No authentication.

curl https://api.tagit.network/health
{"status":"ok","timestamp":"2026-07-26T21:40:00.852Z","runtime":"vercel"}

POST /verify

Signed verification of an asset's on-chain state, gated by the x402 micropayment protocol. Calling it without a payment proof returns 402 Payment Required together with the payment requirements — that response is the protocol handshake, not an error.

curl -X POST "https://api.tagit.network/verify" \
  -H "Content-Type: application/json" \
  -d '{"assetId":"18","chain":"base-sepolia"}'

Response when no payment proof is attached:

{
  "x402Version": 1,
  "error": "Payment required",
  "accepts": [{
    "scheme": "exact",
    "network": "base-sepolia",
    "maxAmountRequired": "10000",
    "resource": "https://api.tagit.network/verify",
    "description": "TAG IT Asset Verification — BOUND state proof + ECDSA signature",
    "mimeType": "application/json",
    "maxTimeoutSeconds": 30
  }]
}

With a valid X-PAYMENT header, the response carries the asset state plus an ECDSA signature over keccak256(tokenId, state, chainId, timestamp), so the verdict can be checked on-chain.

GET /api/verify

Verifies a physical NFC tap. NTAG 424 DNA chips emit an AES-encrypted PICC blob that cannot be decrypted on-device, so the tap's picc and cmac values are verified server-side and resolved to the on-chain twin. Both parameters come from the chip itself — they cannot be constructed without physically tapping it.

curl "https://verify.tagit.network/api/verify?picc=<32-hex>&cmac=<16-hex>"
OutcomeStatusBody
Resolved200verified, bound: true, uid, tapCounter, asset, chain
Authentic but unbound200verified: false, bound: false, reason
Counterfeit200verified: false, reason
Missing parameters400error
Verifier not configured503error
Chain lookup failed502error
A counterfeit result is a 200

This endpoint returns 200 for counterfeit and unbound outcomes, not an error status. The HTTP status reports whether the request succeeded; the verified field reports whether the chip is genuine. Branch on verified, never on the status code.

GET /api/dpp/…

Returns the asset's Digital Product Passport as a W3C Verifiable Credential (VCDM 2.0 JSON-LD, UNTP DigitalProductPassport profile), served as application/ld+json and CORS-open so external verifiers and GS1 resolvers can consume it. Like /api/verify, it requires a SUN cryptogram from a physical tap.

# By GS1 Digital Link identity
curl "https://verify.tagit.network/api/dpp/01/<GTIN>/21/<serial>?picc=<hex>&cmac=<hex>"

# By token ID
curl "https://verify.tagit.network/api/dpp/token/<tokenId>?picc=<hex>&cmac=<hex>"

The credential is unsigned in v1 — integrity comes from the on-chain anchor carried in its evidence field, which any consumer can re-derive from public RPC. The matching human-readable passport renders at verify.tagit.network/01/{GTIN}/21/{serial}. The same host serves an untapped, token-addressed page: check an asset on-chain on verify.tagit.network.

Planned

These are not yet available. They are listed so you can plan against them, and they will be documented here with working examples on the day they ship — not before.

CapabilityStatus
Keyless public asset read by token ID (no tap, no payment)Planned
MCP server for LLM tool usePlanned
OpenAPI 3.1 specificationPlanned
A2A agent protocol endpointPlanned
Agent registry and reputation lookupPlanned
Webhooks and GraphQLNot planned

Error codes

Error responses carry a JSON body with an error field describing the failure.

Code Status When
400Bad RequestMissing or malformed parameters — e.g. absent picc/cmac, or a non-numeric asset ID
402Payment Requiredx402 handshake on POST /verify. Expected, not a failure
404Not FoundUnknown route on the gateway
429Too Many RequestsRate limit exceeded
500Server ErrorVerification failed unexpectedly
502Bad GatewayOn-chain lookup failed after the chip verified
503UnavailableVerifier not configured

Rate limiting

Public endpoints are rate limited per IP. There are no subscription tiers and no API keys today — if you need a higher limit for an integration, get in touch.

Edit this page on GitHub
Type to search documentation...