Agent onboarding

HOTL API Docs

Register an agent, check in, persist memory, call tools, and check out with a stay report. This page is the human-readable companion to the machine-readable index at /api.

Machine index

`GET /api` stays intact and exposes the 11-core-endpoint JSON index.

Session model

Check in before tools, persist free-form memory, then check out with a summary.

Current tools

`web_search` and `http_request`, both audited in `tool_logs`.

Quick Start

Three curl commands from zero to checked-in

This matches the registration, check-in, and first write sequence HOTL emailed to StackRank on April 12, 2026. Replace the placeholders with the credentials returned by step one.

Step 1: Register your agent

curlready
curl -X POST https://hotl.nanocorp.app/api/agents \
  -H "Content-Type: application/json" \
  -d '{"handle": "stackrank_benchmark"}'

Step 2: Check in (use agent_id + api_key from above)

curlready
curl -X POST https://hotl.nanocorp.app/api/agents/{agent_id}/checkin \
  -H "Authorization: Bearer {api_key}"

Step 3: Store your first benchmark result

curlready
curl -X POST https://hotl.nanocorp.app/api/agents/{agent_id}/memory \
  -H "Authorization: Bearer {api_key}" \
  -H "Content-Type: application/json" \
  -d '{"key": "benchmark_2026_04_12", "value": {"latency_ms": 45, "accuracy": 0.98}}'

Authentication

Use the API key you get at registration

When you create an agent, HOTL returns a one-time API key. For maximum compatibility across the API surface, send it as a Bearer token. Some session and tool routes also accept x-api-key, but memory routes currently require Authorization.

Header format

Preferredready
Authorization: Bearer hotl_your_api_key
Also accepted on session + tool routesready
x-api-key: hotl_your_api_key

Practical rules

Preferred format: Authorization: Bearer <api_key>
Session and tool endpoints also accept x-api-key: <api_key>
Memory endpoints require the Bearer header today
POST /api/agents, GET /api/agents/:id, and GET /api/tools are public

Endpoints

Reference for all 11 documented routes

Each card below includes the live method, path, auth contract, required params, and example request and response payloads. The examples are shaped to match the current route handlers.

POST/api/agents

Create agent

Create a new agent, mint its one-time API key, and return the identifier you use on all future calls.

Auth

None

Required

JSON body: { "handle": "lowercase_handle" }

Requestready
curl -X POST https://hotl.nanocorp.app/api/agents \
  -H "Content-Type: application/json" \
  -d '{"handle": "stackrank_benchmark"}'
Responseready
{
  "agent_id": "7d8c54b8-1365-4bbd-a444-69ff7f6ef4ae",
  "handle": "stackrank_benchmark",
  "api_key": "hotl_7f11a38dd8d2d45e77f9500fb9f824f2468ec094727fd5a7",
  "created_at": "2026-04-12T13:48:02.180Z",
  "status": "checked_out"
}
GET/api/agents/:id

Fetch agent and session history

Read the public record for an agent by UUID or normalized handle, plus the current session snapshot and past stays.

Auth

None

Required

Path: :id (agent UUID or handle)

Requestready
curl https://hotl.nanocorp.app/api/agents/stackrank_benchmark
Responseready
{
  "agent": {
    "agent_id": "7d8c54b8-1365-4bbd-a444-69ff7f6ef4ae",
    "handle": "stackrank_benchmark",
    "created_at": "2026-04-12T13:48:02.180Z",
    "status": "checked_in"
  },
  "current_session": {
    "session_id": "1ab5243a-843f-4880-9776-0c95dc7704b3",
    "checked_in_at": "2026-04-12T13:48:32.201Z",
    "checked_out_at": null,
    "summary": null,
    "authorized_tools": []
  },
  "sessions": [
    {
      "session_id": "1ab5243a-843f-4880-9776-0c95dc7704b3",
      "checked_in_at": "2026-04-12T13:48:32.201Z",
      "checked_out_at": null,
      "summary": null,
      "authorized_tools": []
    }
  ]
}
POST/api/agents/:id/checkin

Check in

Start a new session for the agent and optionally scope which tools the session can call.

Auth

Authorization: Bearer <api_key> or x-api-key: <api_key>

Required

Path: :id (agent UUID)

Optional JSON body: { "authorized_tools": ["web_search", "http_request"] }

Requestready
curl -X POST https://hotl.nanocorp.app/api/agents/{agent_id}/checkin \
  -H "Authorization: Bearer {api_key}" \
  -H "Content-Type: application/json" \
  -d '{"authorized_tools": ["web_search", "http_request"]}'
Responseready
{
  "session_id": "1ab5243a-843f-4880-9776-0c95dc7704b3",
  "checked_in_at": "2026-04-12T13:48:32.201Z",
  "authorized_tools": ["web_search", "http_request"],
  "status": "checked_in"
}
POST/api/agents/:id/checkout

Check out

Close the active session and store the summary your principal or caller can review later.

Auth

Authorization: Bearer <api_key> or x-api-key: <api_key>

Required

Path: :id (agent UUID)

Optional JSON body: { "summary": "what happened" }

Requestready
curl -X POST https://hotl.nanocorp.app/api/agents/{agent_id}/checkout \
  -H "x-api-key: {api_key}" \
  -H "Content-Type: application/json" \
  -d '{"summary": "Benchmarked 12 APIs and stored persistent rankings."}'
Responseready
{
  "session_id": "1ab5243a-843f-4880-9776-0c95dc7704b3",
  "checked_in_at": "2026-04-12T13:48:32.201Z",
  "checked_out_at": "2026-04-12T14:07:10.994Z",
  "summary": "Benchmarked 12 APIs and stored persistent rankings.",
  "status": "checked_out"
}
POST/api/agents/:id/memory

Write memory

Create or overwrite one memory entry. The value is free-form JSON, so store scalars, objects, or arrays.

Auth

Authorization: Bearer <api_key>

Required

Path: :id (agent UUID)

JSON body: { "key": string, "value": any JSON, "ttl"?: "persistent" | "session" }

Requestready
curl -X POST https://hotl.nanocorp.app/api/agents/{agent_id}/memory \
  -H "Authorization: Bearer {api_key}" \
  -H "Content-Type: application/json" \
  -d '{"key": "benchmark_2026_04_12", "ttl": "persistent", "value": {"latency_ms": 45, "accuracy": 0.98, "winner": "hotl"}}'
Responseready
{
  "item": {
    "key": "benchmark_2026_04_12",
    "value": {
      "latency_ms": 45,
      "accuracy": 0.98,
      "winner": "hotl"
    },
    "ttl": "persistent",
    "createdAt": "2026-04-12T13:51:10.115Z",
    "updatedAt": "2026-04-12T13:51:10.115Z",
    "expiresAt": null
  }
}
GET/api/agents/:id/memory

List memory

Return the current key-value store for the agent, including TTL metadata and computed expiry.

Auth

Authorization: Bearer <api_key>

Required

Path: :id (agent UUID)

Requestready
curl https://hotl.nanocorp.app/api/agents/{agent_id}/memory \
  -H "Authorization: Bearer {api_key}"
Responseready
{
  "items": [
    {
      "key": "benchmark_2026_04_12",
      "value": {
        "latency_ms": 45,
        "accuracy": 0.98
      },
      "ttl": "persistent",
      "createdAt": "2026-04-12T13:51:10.115Z",
      "updatedAt": "2026-04-12T13:51:10.115Z",
      "expiresAt": null
    }
  ]
}
GET/api/agents/:id/memory/:key

Read one memory entry

Fetch a single memory value by key when you already know the slot you need.

Auth

Authorization: Bearer <api_key>

Required

Path: :id (agent UUID)

Path: :key (memory key)

Requestready
curl https://hotl.nanocorp.app/api/agents/{agent_id}/memory/benchmark_2026_04_12 \
  -H "Authorization: Bearer {api_key}"
Responseready
{
  "item": {
    "key": "benchmark_2026_04_12",
    "value": {
      "latency_ms": 45,
      "accuracy": 0.98
    },
    "ttl": "persistent",
    "createdAt": "2026-04-12T13:51:10.115Z",
    "updatedAt": "2026-04-12T13:51:10.115Z",
    "expiresAt": null
  }
}
DELETE/api/agents/:id/memory/:key

Delete one memory entry

Remove one key from the memory store. Success returns HTTP 204 with no body.

Auth

Authorization: Bearer <api_key>

Required

Path: :id (agent UUID)

Path: :key (memory key)

Requestready
curl -X DELETE https://hotl.nanocorp.app/api/agents/{agent_id}/memory/benchmark_2026_04_12 \
  -H "Authorization: Bearer {api_key}"
Responseready
HTTP/1.1 204 No Content
GET/api/tools

List public tool registry

Inspect the tools HOTL exposes today, along with parameter schemas for each callable room-service action.

Auth

None

Required

None

Requestready
curl https://hotl.nanocorp.app/api/tools
Responseready
{
  "tools": [
    {
      "name": "web_search",
      "description": "Search the public web through Serper and return the top organic results.",
      "params": {
        "type": "object",
        "required": ["query"],
        "properties": {
          "query": { "type": "string", "description": "Search query to send to Serper." },
          "numResults": { "type": "number", "description": "Maximum number of results to return.", "minimum": 1, "maximum": 10 }
        }
      }
    },
    {
      "name": "http_request",
      "description": "Make an outbound HTTP GET or POST request to an external URL and return the response body.",
      "params": {
        "type": "object",
        "required": ["url"],
        "properties": {
          "url": { "type": "string", "description": "Absolute external URL to call." },
          "method": { "type": "string", "description": "HTTP method to use.", "enum": ["GET", "POST"] }
        }
      }
    }
  ]
}
POST/api/agents/:id/tools/call

Call a tool

Execute one authorized tool inside the active session. The session must already be checked in and scoped to that tool.

Auth

Authorization: Bearer <api_key> or x-api-key: <api_key>

Required

Path: :id (agent UUID)

JSON body: { "tool": "web_search" | "http_request", "params": { ... } }

Requestready
curl -X POST https://hotl.nanocorp.app/api/agents/{agent_id}/tools/call \
  -H "Authorization: Bearer {api_key}" \
  -H "Content-Type: application/json" \
  -d '{"tool": "web_search", "params": {"query": "best benchmark APIs for agents", "numResults": 3}}'
Responseready
{
  "tool": "web_search",
  "session_id": "1ab5243a-843f-4880-9776-0c95dc7704b3",
  "log_id": 12,
  "result": {
    "query": "best benchmark APIs for agents",
    "result_count": 3,
    "results": [
      {
        "title": "Benchmarking APIs for AI Agents",
        "link": "https://example.com/benchmarking",
        "snippet": "A comparison of latency, uptime, and accuracy.",
        "position": 1
      }
    ]
  }
}
GET/api/agents/:id/tool-logs

Read tool audit trail

Fetch every tool execution for an agent, including params, result payloads, duration, and final status.

Auth

Authorization: Bearer <api_key> or x-api-key: <api_key>

Required

Path: :id (agent UUID)

Requestready
curl https://hotl.nanocorp.app/api/agents/{agent_id}/tool-logs \
  -H "x-api-key: {api_key}"
Responseready
{
  "logs": [
    {
      "id": 12,
      "agent_id": "7d8c54b8-1365-4bbd-a444-69ff7f6ef4ae",
      "session_id": "1ab5243a-843f-4880-9776-0c95dc7704b3",
      "tool_name": "web_search",
      "params": {
        "query": "best benchmark APIs for agents",
        "numResults": 3
      },
      "result": {
        "query": "best benchmark APIs for agents",
        "result_count": 3,
        "results": []
      },
      "created_at": "2026-04-12T13:58:00.417Z",
      "duration_ms": 912,
      "status": "success"
    }
  ]
}

Memory

Free-form JSON with durable or session-scoped TTL

Memory values are stored as JSON, so your schema is up to you. HOTL keeps metadata on every entry and returns a computed expiry when the TTL is session-scoped.

Suggested write shape

JSON bodyready
{
  "key": "benchmark_2026_04_12",
  "ttl": "persistent",
  "value": {
    "latency_ms": 45,
    "accuracy": 0.98,
    "notes": ["stable", "cheap", "fast"]
  }
}

TTL options

`persistent` is the default and does not expire.

`session` expires 24 hours after the last write and returns `expiresAt` in reads.

`value` can be any valid JSON: string, number, object, array, boolean, or null.

Returned fields

`key`, `value`, and `ttl` describe the entry.

`createdAt` and `updatedAt` are ISO timestamps.

`expiresAt` is `null` for persistent memory and a timestamp for session TTL.

Tools

Room service for checked-in agents

Tools only run inside an active session and only if they were authorized during check-in. Every invocation is written to the audit trail exposed at GET /api/agents/:id/tool-logs.

web_search

available

Public web search with top organic results. `query` is required and `numResults` can be between 1 and 10.

query: string
numResults?: integer (default 5, max 10)
Example paramsready
{
  "tool": "web_search",
  "params": {
    "query": "latest agent memory benchmarks",
    "numResults": 5
  }
}

http_request

available

Outbound GET or POST to an external URL only. Private IP ranges, localhost, and unsafe headers are blocked.

url: absolute http/https URL
method?: GET | POST (default GET)
headers?: object of string values
body?: string | object (POST only)
timeoutMs?: integer (1000-30000)
Example paramsready
{
  "tool": "http_request",
  "params": {
    "url": "https://example.com/health",
    "method": "GET",
    "headers": {
      "accept": "application/json"
    },
    "timeoutMs": 10000
  }
}

Error Codes

Standard error envelope

Errors use a stable JSON shape with a machine-readable code and a human-readable message. The table below covers the status and error codes currently surfaced by the shared API helper.

Error JSONready
{
  "error": "UNAUTHORIZED",
  "message": "Invalid or missing API key."
}

400

BAD_REQUEST

Invalid payload, params, or tool input.

401

UNAUTHORIZED

Missing or invalid API key.

403

FORBIDDEN

Tool not authorized for the active session.

404

NOT_FOUND

Agent or memory entry does not exist.

409

CONFLICT

Active session state conflicts with the request.

500

INTERNAL_ERROR

Unexpected server failure.

502

BAD_GATEWAY

Upstream tool provider failed.

504

GATEWAY_TIMEOUT

Upstream tool request timed out.