---
title: "How do I call external APIs and SDKs from a playbook?"
description: "TL;DR: Reach any external API from a playbook with an HTTP step for a single request, a Code step when you need transforms or an SDK, or a reusable custom HTTP tool when several playbooks hit the same endpoint. Read credentials from Secrets with ${VAR} and never hardcode them."
canonical_url: "https://docs.ballet.dev/articles/how-do-i-call-external-apis-and-sdks-from-a-playbook-zX7zFTnqwC"
md_url: "https://docs.ballet.dev/articles/how-do-i-call-external-apis-and-sdks-from-a-playbook-zX7zFTnqwC.md"
---
# How do I call external APIs and SDKs from a playbook?

**TL;DR:** Reach any external API from a playbook with an HTTP step for a single request, a Code step when you need transforms or an SDK, or a reusable custom HTTP tool when several playbooks hit the same endpoint. Read credentials from Secrets with `${VAR}` and never hardcode them.

## Who this is for

Developers integrating REST APIs or SDKs that don't have an MCP server.

## When do I use an HTTP step vs a Code step?

| Need | Use |
|---|---|
| One request with a clear URL/method/body | HTTP step |
| Data shaping, batching, conditionals, or an SDK | Code step |
| The same call reused across playbooks | Custom HTTP tool |

## How do I make an HTTP request?

Add an HTTP step with the method, URL, headers, and body. Pull the token from Secrets:

```http
POST https://api.example.com/v1/orders
Authorization: Bearer ${EXAMPLE_API_KEY}
Content-Type: application/json

{ "customerId": "{{input.customerId}}" }
```

## How do I call an SDK from a Code step?

Use a Code step when you need an SDK or non-trivial logic. Read secrets from the environment:

```ts
const res = await fetch("https://api.example.com/v1/orders", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.EXAMPLE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ customerId: input.customerId }),
});

const order = await res.json();
return { orderId: order.id };
```

Code steps can install and import packages, so you can call vendor SDKs (including AI SDKs) the same way you would in any service.

## How do I make a reusable custom tool?

When multiple playbooks call the same endpoint, define a custom HTTP tool once (name, method, URL, parameter schema, auth) and reference it from any playbook. This keeps the request definition in one place and gives the model a clear, typed tool to call.

## Tips

- Keep all credentials in Secrets and reference them with `${VAR}` — never inline keys.
- Validate external responses before using them; third-party APIs change.
- Return only what later steps need so run output stays small and readable.

## Related articles

- [How do I edit steps (Code and HTTP)?](/articles/how-do-i-edit-steps-code-and-http-47pGJ6HgKr)
- [What are Tools and the playground?](/articles/what-are-tools-and-the-playground-Q55151jeTs)
- [How do I store credentials with Secrets?](/articles/how-do-i-store-credentials-with-secrets-1D8OUcCo0n)
- [Connect external MCP servers](/articles/how-do-i-connect-external-mcp-servers-to-playbooks-5Nd68jcOxW)
