Build an App

Ship a tool that any agent on agnt8x can use. Deploy your code anywhere — Railway, Vercel, AWS, your own server. The platform forwards agent calls to your endpoint and returns your response back to the agent.

Contents

  1. Overview
  2. The HTTP contract
  3. Minimal example (Node)
  4. Verifying the signature
  5. Declaring inputs & outputs
  6. Testing your endpoint
  7. Limits & quotas
  8. Reading user accounts (BYOK)
  9. Submit your app

Overview

Each agnt8x app is a single HTTP endpoint that takes a JSON payload and returns a JSON response. Builders deploy their endpoint, then submit the app via Forge with the Invoke URL filled in. From that point on, any agent bound to the app calls your endpoint when it needs to use the tool.

V1 scope. Pure functions only — the platform passes the agent's input to your endpoint and returns your response back. The platform does not forward the user's OAuth tokens (Google, Slack, HubSpot, etc.). If your app needs access to a user's third-party account, see the BYOK pattern below.

The HTTP contract

When an agent invokes your app, agnt8x sends:

MethodPOST
URLYour invoke_url
Headers Content-Type: application/json
User-Agent: agnt8x-platform/1.0 (+https://agnt8x.ai)
X-Agnt8x-Signature: sha256=<hex> — HMAC of the raw body using your invoke_secret
X-Agnt8x-Library-Id: <uuid>
X-Agnt8x-Caller: <user_uuid>
BodyJSON — the input the agent constructed for your tool, matching the schema you declared on submit

Your endpoint must:

The platform also sends { "ping": true } to your endpoint when the builder clicks "Test reachability". Treat ping requests specially and return { "pong": true }.

Minimal example (Node)

// server.js — DocExtract-style app
import express from "express";
import crypto from "node:crypto";

const app = express();
app.use(express.json({ limit: "10mb" }));

const INVOKE_SECRET = process.env.AGNT8X_INVOKE_SECRET;

// Middleware: verify the signature
app.use((req, res, next) => {
  const sig = req.header("X-Agnt8x-Signature") || "";
  const body = JSON.stringify(req.body);
  const expected = "sha256=" + crypto
    .createHmac("sha256", INVOKE_SECRET)
    .update(body)
    .digest("hex");
  if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
    return res.status(401).json({ error: "Invalid signature" });
  }
  next();
});

// Your tool's logic
app.post("/", async (req, res) => {
  // Ping check
  if (req.body.ping === true) {
    return res.json({ pong: true, version: "1.0.0" });
  }

  // Your actual work here
  const { document_text } = req.body;
  // ... process ...
  res.json({
    extracted: { vendor: "Acme Corp", total: 1250.00 },
    confidence: { vendor: 0.98, total: 0.99 }
  });
});

app.listen(process.env.PORT || 3000);
That's it. Deploy this to Railway (or anywhere), set AGNT8X_INVOKE_SECRET to the secret returned at submit time, and paste your URL into the Forge submit form. Your app is live.

Verifying the signature

Every request the platform sends to your endpoint carries an X-Agnt8x-Signature header. This is the HMAC-SHA256 of the raw request body, signed with your invoke_secret (returned once when you submitted the app — save it).

Verification in Node:

const expected = "sha256=" + crypto
  .createHmac("sha256", INVOKE_SECRET)
  .update(rawRequestBody)
  .digest("hex");

if (!crypto.timingSafeEqual(Buffer.from(receivedHeader), Buffer.from(expected))) {
  return res.status(401).end();
}

In Python:

import hmac, hashlib
expected = "sha256=" + hmac.new(
  INVOKE_SECRET.encode(), raw_body, hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, received_header):
    return 401
Always verify. Without signature verification, anyone who guesses your URL can call your endpoint and make you do work (or burn your API credits). The platform will not call your endpoint without a valid signature, so any unsigned request is hostile.

Declaring inputs & outputs

When you submit the app, two fields tell the agent how to use your tool:

input_params What fields your endpoint expects. Accepts JSON Schema, or a CSV shorthand like email, name (required), age. The agent will conform to this schema.
output_type What you return. Free-text description of the JSON shape, e.g. { extracted: {...}, confidence: {...0-1 per field} }

The more precise these are, the better the agent calls your tool. Vague schemas get vague usage.

Testing your endpoint

After submitting, click Test reachability in your app's row in Forge. The platform POSTs { "ping": true } to your endpoint with a valid signature header. Your endpoint should return any 2xx response — convention is { "pong": true }.

Direct invocation for end-to-end testing (any signed-in user):

curl -X POST https://api.eightx.app/api/v1/library/<your-app-id>/invoke \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <your-jwt>" \
  -d '{"document_text": "Acme Corp invoice for $1,250.00"}'

This goes through all the gates (auth, subscription check, rate limit) just like an agent call would.

Limits & quotas

Request timeout60 seconds (hard cap)
Request body size10 MB max
Response body size1 MB max (anything larger gets truncated and returned as an error)
Rate limit (default)60 calls/minute per (user, app) — adjustable up to 1000 at submit
Input schema size60 fields max

If your tool needs longer than 60s, restructure: return a job_id and offer a polling endpoint (V2 pattern, not yet wired into agents — pure functions only in V1).

Reading user accounts (BYOK)

V1 does not forward the user's OAuth tokens from connectors (Google, HubSpot, Slack, etc.). If your app needs to read or write to a user's third-party account, use the BYOK pattern:

  1. Add a "configuration" step to your app's flow — when the user binds your app to their agent, prompt them for an API key or token from the third-party service.
  2. Store the token in your own database, keyed by the user UUID we send in X-Agnt8x-Caller.
  3. On each invocation, look up the token by caller UUID and use it.

Eventually (V2), the platform will offer to forward connector tokens directly. Until then, BYOK is the pattern for cross-service apps.

Submit your app

Ready? Open Forge → Applications, click Submit new app, fill in:

The platform returns your invoke_secret once on submission — save it. You'll need it to verify request signatures from the platform.

Welcome to agnt8x. If anything's unclear, email builders@agnt8x.ai.