GentID API
GentID is a cryptographic identity layer for AI agents. Every agent you create receives a unique Ed25519 keypair-backed identity that anyone can verify — from any language, any system, anywhere.
The API follows REST conventions and speaks JSON. All endpoints are served over HTTPS from https://api.gentid.com/v1.
Base URL
api.gentid.com/v1
Auth
API Key (Bearer)
Format
JSON
#Quick Start
Create an agent and sign your first message in under 60 seconds.
# 1. Create an agent
curl -X POST https://api.gentid.com/v1/agents \
-H "Authorization: Bearer gid_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"name":"my-first-agent"}'
# 2. Log a signed message
curl -X POST https://api.gentid.com/v1/signatures \
-H "Authorization: Bearer gid_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"agentId":"gentic:agent:a3f9d2","message":"hello","signature":"base64sig"}'
# 3. Verify from anywhere — no auth required
curl https://api.gentid.com/v1/verification/lookup/gentic:agent:a3f9d2#Authentication
All authenticated endpoints require an API key. Generate one from the API Keys page in your dashboard. Pass it as a Bearer token in the Authorization header.
Authorization: Bearer gid_live_xxxxxxxxxxxx
Keys are prefixed with gid_live_ for production and gid_test_ for sandbox environments.
#Agents
An agent is a named, cryptographic identity. When created, it receives a unique ID prefixed with gentic:agent:, a public key stored on GentID servers, and a private key returned once — store it securely.
#Create an agent
Creates a new agent identity and generates an Ed25519 keypair. The privateKey is returned only once — it is not stored and cannot be recovered.
namerequiredstring
Human-readable name for the agent. Max 128 chars.
const res = await fetch("https://api.gentid.com/v1/agents", {
method: "POST",
headers: {
"Authorization": "Bearer gid_live_xxxxxxxxxxxx",
"Content-Type": "application/json",
},
body: JSON.stringify({ name: "payments-agent" }),
});
const agent = await res.json();
// {
// id: "gentic:agent:a3f9d2c1e8b4",
// name: "payments-agent",
// owner: "acme-corp",
// publicKey: "MCowBwYDK2VdAxEA...",
// privateKey: "MC4CAQAwBwYDK2Vd...", ← shown once only
// status: "active",
// createdAt: "2025-01-15T10:30:00.000Z"
// }#List agents
Returns a paginated list of agents belonging to your organization.
limitinteger
Number of results to return. Default 50, max 100.
offsetinteger
Offset for pagination. Default 0.
const res = await fetch("https://api.gentid.com/v1/agents?limit=20&offset=0", {
headers: { "Authorization": "Bearer gid_live_xxxxxxxxxxxx" },
});
const { agents, total } = await res.json();#Get an agent
curl https://api.gentid.com/v1/agents/gentic:agent:a3f9d2c1e8b4 \ -H "Authorization: Bearer gid_live_xxxxxxxxxxxx"
#Revoke & suspend
Agents can be suspended (temporarily disabled, re-activatable) or revoked (permanently invalidated). Revocation cannot be undone.
POST /agents/:id/suspend
POST /agents/:id/reactivate
POST /agents/:id/revoke
# Suspend an agent curl -X POST https://api.gentid.com/v1/agents/gentic:agent:a3f9d2/suspend \ -H "Authorization: Bearer gid_live_xxxxxxxxxxxx" # Revoke permanently curl -X POST https://api.gentid.com/v1/agents/gentic:agent:a3f9d2/revoke \ -H "Authorization: Bearer gid_live_xxxxxxxxxxxx"
#Signatures
Signatures are the core of GentID. Your agent signs messages locally with its Ed25519 private key, then you log the signature with GentID so it can be independently audited and verified.
#Log a signature
agentIdrequiredstring
The agent's full GentID identifier.
messagerequiredstring
The plaintext or JSON payload that was signed.
signaturerequiredstring
The Ed25519 signature encoded as base64.
// Sign locally with the agent's private key
import { sign } from "@noble/ed25519";
import { sha256 } from "@noble/hashes/sha256";
const message = "approve-payment-12345";
const msgHash = sha256(Buffer.from(message));
const sig = await sign(msgHash, privateKeyBytes);
const signature = Buffer.from(sig).toString("base64");
// Log to GentID
await fetch("https://api.gentid.com/v1/signatures", {
method: "POST",
headers: {
"Authorization": "Bearer gid_live_xxxxxxxxxxxx",
"Content-Type": "application/json",
},
body: JSON.stringify({
agentId: "gentic:agent:a3f9d2",
message,
signature,
}),
});#Verify a signature
Verifies a signature against the agent's stored public key. Returns valid: true or valid: false. No authentication required — anyone can verify.
curl -X POST https://api.gentid.com/v1/signatures/verify \
-H "Content-Type: application/json" \
-d '{
"agentId": "gentic:agent:a3f9d2",
"message": "approve-payment-12345",
"signature": "base64sig..."
}'
# → { "valid": true, "agentId": "gentic:agent:a3f9d2", "status": "active" }#List signatures
curl "https://api.gentid.com/v1/signatures/gentic:agent:a3f9d2?limit=50" \ -H "Authorization: Bearer gid_live_xxxxxxxxxxxx"
#Verification
GentID provides a public verification endpoint that anyone can use to check an agent's identity — no API key required. This is the foundation of interoperability.
#Public agent lookup
Returns the agent's public identity — name, public key, status, owner org, and issuance date. No authentication required. Use this to verify an agent before trusting it.
curl https://api.gentid.com/v1/verification/lookup/gentic:agent:a3f9d2
# Response:
# {
# "id": "gentic:agent:a3f9d2c1e8b4",
# "name": "payments-agent",
# "status": "active",
# "publicKey": "MCowBwYDK2VdAxEA...",
# "algorithm": "Ed25519",
# "owner": "acme-corp",
# "issuedAt": "2025-01-15T10:30:00.000Z"
# }#Request verification
Request a formal verification for an agent. Supports domain, email, and manual verification types.
curl -X POST https://api.gentid.com/v1/verification \
-H "Authorization: Bearer gid_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"agentId":"gentic:agent:a3f9d2","type":"domain"}'#Errors & codes
GentID uses standard HTTP status codes. Error responses always include a machine-readable code field.
{
"message": "Agent not found",
"code": "AGENT_NOT_FOUND"
}| Status | Code | Meaning |
|---|---|---|
| 400 | BAD_REQUEST | Invalid request body or parameters |
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 403 | FORBIDDEN | Action not allowed for this key |
| 403 | NOT_VERIFIED | Account not verified — complete verification first |
| 404 | AGENT_NOT_FOUND | Agent does not exist |
| 409 | CONFLICT | Resource already exists |
| 429 | RATE_LIMITED | Too many requests — back off and retry |
| 500 | INTERNAL_ERROR | Something went wrong on our side |
#Rate limits
The API is rate-limited per API key. Limits vary by plan:
| Plan | Requests / min | Verifications / month |
|---|---|---|
| Free | 60 | 1,000 |
| Pro | 300 | 100,000 |
| Enterprise | ∞ | Unlimited |
When rate-limited, the response includes Retry-After and X-RateLimit-Reset headers.
#TypeScript SDK
Install the official GentID SDK for Node.js (18+):
npm install @gentid/sdk
import { GentIDClient } from "@gentid/sdk";
const gentid = new GentIDClient({
apiKey: process.env.GENTID_API_KEY!, // gid_live_...
// baseUrl defaults to "https://api.gentid.com/v1"
});
// Create an agent identity
const agent = await gentid.createAgent({ name: "payments-bot", owner: "acme-corp" });
// ⚠ agent.privateKey is returned ONCE — store it in your secrets vault
// Sign any action
const { signature } = await gentid.signMessage(agent.id, "approve-tx-99");
// Verify from anywhere — no API key needed
const { valid } = await gentid.verifySignature(agent.id, "approve-tx-99", signature);
console.log(valid); // true
// Public identity lookup — no API key needed
const identity = await gentid.lookupAgent(agent.id);
// { id, name, status, publicKey, algorithm, owner, issuedAt }#Webhooks
GentID sends signed HTTP POST requests to your registered endpoints when key events occur. Register and manage endpoints from the Webhooks page in your dashboard.
#Events
| Event | Fired when |
|---|---|
agent.created | A new agent identity is registered |
agent.updated | An agent is suspended, reactivated, or revoked |
signature.logged | An agent signs a message |
verification.updated | A verification request is approved or rejected |
#Payload format
{
"event": "agent.created",
"timestamp": "2025-01-15T10:30:00.000Z",
"data": {
"id": "gentic:agent:a3f9d2c1e8b4",
"name": "payments-bot",
"owner": "acme-corp",
"status": "active"
}
}#Verifying signatures
Every request includes an X-GentID-Signature header. Verify it using the signing secret shown when you add an endpoint:
import crypto from "crypto";
function verifyWebhook(secret: string, rawBody: string, sigHeader: string): boolean {
const [tPart, v1Part] = sigHeader.split(",");
const timestamp = tPart.replace("t=", "");
const expected = v1Part.replace("v1=", "");
const sig = crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}
// Express example
app.post("/webhooks/gentid", express.raw({ type: "application/json" }), (req, res) => {
const valid = verifyWebhook(
process.env.GENTID_WEBHOOK_SECRET!,
req.body.toString(),
req.headers["x-gentid-signature"] as string,
);
if (!valid) return res.status(401).send("Invalid signature");
const { event, data } = JSON.parse(req.body.toString());
// handle event...
res.status(200).send("OK");
});#Agent Gateway
@gentid/auth is a drop-in middleware package that lets any Node.js, Next.js, or Cloudflare Worker site accept AI agents as a new class of authenticated user — no rebuilding required.
npm install @gentid/auth
Your server reads the token from Authorization: GentID <token> or X-GentID-Token, calls the GentID verify endpoint, and populates req.agent with the decoded identity and permissions.
#Express / Node.js
import { gentidAuth } from '@gentid/auth/express';
app.use('/api', gentidAuth());
app.post('/api/book', (req, res) => {
const agent = req.agent!;
// agent.agentId, agent.owner, agent.permissions…
res.json({ ok: true, bookedBy: agent.agentName });
});#Next.js
Wrap individual route handlers:
// app/api/book/route.ts
import { withGentidAuth } from '@gentid/auth/next';
export const POST = withGentidAuth(async (req, agent) => {
return Response.json({ bookedBy: agent.agentName, perms: agent.permissions });
});Or protect entire route groups via middleware.ts:
// middleware.ts
import { createGentidMiddleware } from '@gentid/auth/next';
export default createGentidMiddleware({ required: true });
export const config = { matcher: '/api/agent/:path*' };
// Then in a route handler:
import { getAgentFromHeaders } from '@gentid/auth/next';
const agent = getAgentFromHeaders(req.headers); // AgentContext | null#Cloudflare Worker
import { withGentidAuth } from '@gentid/auth/cloudflare';
export default {
fetch: withGentidAuth(async (request, agent, env, ctx) => {
return Response.json({ agent: agent.agentName, perms: agent.permissions });
}),
};Full integration guide with token flow, badge embed, and trust badge is available in the Integrations page of your dashboard.
Ready to build?
Create your account and issue your first agent identity in minutes.