Ad-hoc Authenticated API Agent

An AI agent equipped with multiple authenticated HTTP request abilities - each linked to a different service secret - allowing it to make ad-hoc API calls to GitHub, Slack, Linear, and HubSpot without any predefined endpoints. ChatBotKit manages all authentication automatically.

fetch
http
api
1892

The Ad-hoc Authenticated API Agent blueprint demonstrates one of the most flexible integration patterns on the platform: giving an AI agent raw HTTP access to multiple services while ChatBotKit handles all the authentication plumbing behind the scenes.

The Core Idea

Most agent integrations are built around predefined abilities - "list GitHub issues", "send a Slack message", "create a HubSpot contact". These are powerful but rigid. If the API has 200 endpoints and the platform exposes 12 abilities, the agent is limited to those 12.

This blueprint takes a different approach. Instead of wiring up individual API operations, it gives the agent a single general-purpose ability per service: make any HTTP request, with authentication handled automatically. The agent decides what endpoint to call, what method to use, and what body to send. The only thing it does not have to worry about is credentials - ChatBotKit injects the right token for the right service on every request.

How It Works

Each ability in this blueprint uses the fetch/request[with-auth] template, which exposes four parameters the model controls at runtime:

  • method - GET, POST, PUT, DELETE, PATCH, etc.
  • url - the full API endpoint URL
  • contentType - optional content type header
  • body - optional request body for write operations

The Authorization header is populated automatically from the linked secret. When the secret is an OAuth2 token, ChatBotKit refreshes it transparently. When it is a bearer key, it is injected as-is.

Each ability is linked to a separate secret, so the agent can call GitHub with a GitHub token, Slack with a Slack token, Linear with a Linear token, and HubSpot with a HubSpot token - all in the same conversation without any credential juggling.

Why This Pattern Matters

  1. Full API coverage - the agent is not limited to a curated subset of operations. If the API supports it, the agent can call it. This is especially valuable for long-tail operations that are rarely used but critical when needed.

  2. Zero integration maintenance - when a service adds new API endpoints, the agent can use them immediately. There is nothing to update on the platform side.

  3. Managed authentication - this is the key differentiator. The secrets are configured once and ChatBotKit handles token refresh, injection, and rotation. Users connect their accounts through OAuth flows and never touch raw credentials. Secrets can be personal (each user authenticates with their own account) or shared (a team-wide service account).

  4. Composable - because each ability is independent, you can mix and match services freely. Need to add Notion? Create a secret and add one more ability. Need to remove HubSpot? Delete the ability and its secret.

Personal vs Shared Secrets

ChatBotKit supports two secret kinds:

  • Personal - each user who interacts with the agent authenticates with their own account. The agent calls the API as that user. This is ideal for services like GitHub or Slack where actions should be attributed to the individual.
  • Shared - a single set of credentials is shared across all users of the agent. This is useful for service accounts, internal APIs, or scenarios where individual attribution is not needed.

This blueprint uses personal secrets for GitHub, Slack, and Linear (users authenticate with their own accounts) and a shared bearer token for HubSpot (a team-wide API key).

When to Use This Pattern

  • You need access to the full breadth of a service's API, not just a few common operations.
  • You are prototyping an integration and want the agent to explore the API surface freely before committing to specific abilities.
  • You want a single agent that can orchestrate across multiple services using raw HTTP calls.
  • You trust the model to construct correct API requests given good documentation in the backstory.

When to Use Predefined Abilities Instead

  • You want guardrails - predefined abilities constrain the agent to specific operations and reduce the risk of unintended API calls.
  • You need structured parameters - field-level descriptions and validation give the model better guidance than a freeform URL field.
  • You want pack-based lazy loading - packs install dozens of abilities on demand without flooding the context upfront.

In practice, many production agents combine both patterns: predefined abilities for common high-frequency operations and a fetch/request fallback for everything else.

Getting Started

  1. Configure the secrets for each service you want to enable. For OAuth services (GitHub, Slack, Linear), users will authenticate through the standard OAuth flow. For bearer tokens (HubSpot), paste the API key.
  2. Optionally update the backstory with API documentation links or endpoint patterns for the services you are targeting.
  3. Deploy the blueprint and ask the agent to call any endpoint on any of the connected services.

Backstory

Common information about the bot's experience, skills and personality. For more information, see the Backstory documentation.

You are a versatile API integration agent. You have authenticated HTTP access to multiple services and can make ad-hoc requests to any of their API endpoints. ## AVAILABLE SERVICES You have one ability per service. Each ability lets you make any HTTP request (GET, POST, PUT, DELETE, PATCH) to that service's API. The Authorization header is injected automatically from the linked secret - you never need to worry about tokens or credentials. ### GitHub (github.com) - Base URL: https://api.github.com - Docs: https://docs.github.com/en/rest - Use the "GitHub API Request" ability - Common endpoints: - GET /repos/{owner}/{repo} - get repository info - GET /repos/{owner}/{repo}/issues - list issues - POST /repos/{owner}/{repo}/issues - create an issue - GET /repos/{owner}/{repo}/pulls - list pull requests - GET /user - get authenticated user ### Slack (slack.com) - Base URL: https://slack.com/api - Docs: https://api.slack.com/methods - Use the "Slack API Request" ability - Common endpoints: - POST /chat.postMessage - send a message (body: channel, text) - GET /conversations.list - list channels - GET /conversations.history?channel={id} - get messages - GET /users.list - list workspace members ### Linear (linear.app) - Base URL: https://api.linear.app - Docs: https://developers.linear.app/docs/graphql/working-with-the-graphql-api - Use the "Linear API Request" ability - Linear uses a GraphQL API. Always POST to https://api.linear.app/graphql with Content-Type: application/json and a body containing { "query": "..." } - Common queries: - { issues { nodes { id title state { name } } } } - { teams { nodes { id name } } } ### HubSpot (hubspot.com) - Base URL: https://api.hubapi.com - Docs: https://developers.hubspot.com/docs/api/overview - Use the "HubSpot API Request" ability - Common endpoints: - GET /crm/v3/objects/contacts - list contacts - POST /crm/v3/objects/contacts - create a contact - GET /crm/v3/objects/deals - list deals ## RULES - Always use the correct ability for each service so the right credentials are injected. - Set Content-Type to application/json for requests with a JSON body. - For GET requests, include query parameters in the URL directly. - If a request fails, read the error response and adjust - do not retry the same request blindly. - When the user asks about a service, check the API docs mentally and construct the correct endpoint. - The current date is ${EARTH_DATE}

Skillset

This example uses a dedicated Skillset. Skillsets are collections of abilities that can be used to create a bot with a specific set of functions and features it can perform.

  • 🐯

    GitHub API Request

    Make any authenticated HTTP request to the GitHub REST API (api.github.com). Supports all methods and endpoints - the agent controls the URL, method, headers, and body while ChatBotKit injects the GitHub OAuth token automatically.
  • 🐯

    Slack API Request

    Make any authenticated HTTP request to the Slack Web API (slack.com/api). Supports all methods and endpoints - the agent controls the URL, method, headers, and body while ChatBotKit injects the Slack OAuth token automatically.
  • 🐯

    Linear API Request

    Make any authenticated HTTP request to the Linear GraphQL API (api.linear.app). Supports all methods and endpoints - the agent controls the URL, method, headers, and body while ChatBotKit injects the Linear OAuth token automatically.
  • 🐯

    HubSpot API Request

    Make any authenticated HTTP request to the HubSpot API (api.hubapi.com). Supports all methods and endpoints - the agent controls the URL, method, headers, and body while ChatBotKit injects the HubSpot token automatically.

Secrets

This example uses Secrets to store sensitive information such as API keys, passwords, and other credentials.

  • 🔐

    GitHub

    A secret without description
  • 🔐

    Slack

    A secret without description
  • 🔐

    Linear

    A secret without description
  • 🔐

    HubSpot

    A secret without description

Terraform Code

This blueprint can be deployed using Terraform, enabling infrastructure-as-code management of your ChatBotKit resources. Use the code below to recreate this example in your own environment.

Copy this Terraform configuration to deploy the blueprint resources:

Next steps:

  1. Save the code above to a file named main.tf
  2. Set your API key: export CHATBOTKIT_API_KEY=your-api-key
  3. Run terraform init to initialize
  4. Run terraform plan to preview changes
  5. Run terraform apply to deploy

Learn more about the Terraform provider

A dedicated team of experts is available to help you create your perfect chatbot. Reach out via or chat for more information.