Skip to Content
GuidesContextual AccessBuild Your Own

Build Your Own Contextual Access Server

This guide walks through implementing a webhook server that satisfies the Contextual Access Webhook contract. You can write it in any language — the contract is defined by an OpenAPI 3.0 spec.

OpenAPI spec

The canonical contract is maintained in the ArcadeAI/schemas  repository:

You can browse it interactively on the API Reference page.

Generate server stubs

Use the OpenAPI spec with standard code generators to scaffold your server:

LanguageGenerator
Gooapi-codegen , ogen 
Pythonopenapi-generator , datamodel-code-generator 
TypeScriptopenapi-typescript , openapi-generator 

Example (Go with oapi-codegen):

Terminal
curl -sL https://raw.githubusercontent.com/ArcadeAI/schemas/main/logic_extensions/http/1.0/schema.yaml -o schema.yaml oapi-codegen -generate types,server -package server schema.yaml

The logic-extensions-examples  repo uses this approach — see pkg/server/ for the generated types.

Endpoints to implement

Your server needs to expose HTTP POST endpoints for each hook point you want to handle. Endpoint paths are fully configurable in the Dashboard — the defaults are shown below.

EndpointHook pointRequired
POST /accessAccess HookOnly if you need tool access control
POST /prePre-Execution HookOnly if you need tool request validation/modification
POST /postPost-Execution HookOnly if you need tool output filtering/modification

You do not need to implement all endpoints. Only implement the ones you configure in the Dashboard.

Pre-Execution Hook

When: Before each execution.

Request (Arcade sends to your server)

FieldTypeDescription
execution_idstringCorrelates request/response across hooks
toolobjectname, toolkit, version
inputsobjectTool inputs (name → value)
contextobjectauthorization (OAuth per provider), secrets (key names only), metadata, user_id

Response (your server returns)

FieldTypeRequiredDescription
codestringYesOK, CHECK_FAILED, or RATE_LIMIT_EXCEEDED
error_messagestringNoShown to the agent when denying
overrideobjectNoinputs and/or secrets to modify the request

Post-Execution Hook

When: After execution.

Request

FieldTypeDescription
execution_idstringCorrelates with pre-execution hook
toolobjectname, toolkit, version
inputsobjectTool inputs
successbooleanWhether the tool call succeeded
outputanyThe execution output (any JSON type)
execution_codestringStatus from worker
execution_errorstringError message from tool call
contextobjectSame as pre-execution hook

Response

FieldTypeRequiredDescription
codestringYesOK, CHECK_FAILED, or RATE_LIMIT_EXCEEDED
error_messagestringNoShown to the agent when denying
overrideobjectNooutput to replace the response returned to the agent

Access Hook

When: When Arcade needs to know which a can see. Supports batch requests.

Request

FieldTypeDescription
user_idstringUser to check
toolkitsobjectMap of toolkit name → toolkit info (tools, versions, requirements)

Response

Return either an allow list or a deny list (not both):

FieldTypeDescription
onlyobjectIf present, only these tools are allowed (deny list ignored)
denyobjectTools listed here are denied (ignored if only is present)

If you return neither field, the Arcade treats it as “no change” — all remain allowed at this hook.

Response codes (pre and post)

CodeMeaning
OKProceed; optional override is applied
CHECK_FAILEDDeny the operation; error_message is shown to the agent
RATE_LIMIT_EXCEEDEDDeny with rate-limit semantics

Authentication

Arcade sends one of:

  • Bearer: Authorization: Bearer <token> (token from extension config)
  • mTLS: Client certificate during TLS handshake; optional CA cert for server verification

Configure the auth method when creating your extension in the Dashboard.

Failure handling and retries

  • Timeout: Configurable per extension (default 5s); can be overridden per hook. On timeout, the hook’s failure mode applies (Fail closed = block, Fail open = allow).
  • Retries: Optional at the extension level; only for transient failures (5xx, timeout, connection error). 4xx responses are not retried.

Next steps

  • API Reference — Interactive Swagger documentation for the full schema
  • Run an extension — Try the open-source example servers as reference
  • How Hooks Work — Understand execution order, phases, and failure modes
Last updated on