Write a DADL File
You don’t have to write DADL files by hand. The fastest path is asking any LLM that knows the DADL spec:
“Create a DADL for the Stripe API — list customers, create charges, and manage subscriptions.”
Claude, GPT, Gemini — any model generates a working .dadl file in seconds. Drop it into dadl/, add a backend entry, done.
If you use Claude Code with ToolMesh connected, it can create the .dadl file, add the backend entry to config/backends.yaml, and set the credential — all in one session.
The guide below is for when you want to write or edit a DADL by hand — or understand what the LLM generated.
Prerequisites
Section titled “Prerequisites”- A running ToolMesh instance
- Access to the REST API you want to describe
- API credentials (token, key, or OAuth client)
1. Start with the skeleton
Section titled “1. Start with the skeleton”Every DADL file begins with a spec reference and a backend block:
spec: "https://dadl.ai/spec/dadl-spec-v0.1.md"backend: name: my-api type: rest version: "1.0" description: "My API — what it does in one line"The name must be unique across your ToolMesh deployment. It becomes the prefix for all tools (e.g. my-api.list_items). The version is optional but recommended — ToolMesh uses it to detect when a newer DADL is available in the registry.
2. Configure authentication
Section titled “2. Configure authentication”Add an auth block that tells ToolMesh how to inject credentials into requests:
auth: type: bearer credential: my_api_token inject_into: header header_name: Authorization prefix: "Bearer "Common auth patterns:
| Type | inject_into | Key field |
|---|---|---|
| Bearer token | header | header_name: Authorization |
| API key in header | header | header_name: X-API-Key |
| API key in query | query | query_param: api_key |
The credential value references a key in ToolMesh’s credential store — the actual secret is never in the DADL file.
3. Set defaults
Section titled “3. Set defaults”Define headers, pagination, and error handling that apply to all tools:
defaults: headers: Accept: application/json Content-Type: application/json pagination: &default-pagination strategy: page request: page_param: page limit_param: per_page limit_default: 30 behavior: manual max_pages: 10 errors: &standard-errors format: json message_path: "$.message" retry_on: [429, 502, 503] retry_strategy: max_retries: 3 backoff: exponential initial_delay: 1sUse YAML anchors (&default-pagination) so tools can reference these with *default-pagination.
4. Define tools
Section titled “4. Define tools”Each tool maps to one API endpoint:
tools: list_items: method: GET path: /items access: read description: "List all items, optionally filtered by status" params: status: type: string in: query description: "Filter by status" enum: [active, archived] page: type: integer in: query pagination: *default-pagination
get_item: method: GET path: /items/{id} access: read description: "Get a single item by ID" params: id: type: string in: path required: true
create_item: method: POST path: /items access: write description: "Create a new item" params: name: type: string in: body required: true description: type: string in: body
delete_item: method: DELETE path: /items/{id} access: dangerous description: "Permanently delete an item" params: id: type: string in: path required: trueKey rules:
- Path parameters use
{param}syntax and must havein: path+required: true - Query parameters use
in: query - Body parameters use
in: bodyand are sent as JSON accessclassifies the tool for policy/authorization mapping (see below)- Descriptions are what the AI agent sees — make them specific and actionable
5. Add setup instructions
Section titled “5. Add setup instructions”The setup block tells users how to get API credentials:
setup: credential_steps: - "Go to https://example.com/settings/api" - "Click 'Create API Key'" - "Copy the generated key" env_var: CREDENTIAL_MY_API_TOKEN backends_yaml: | - name: my-api transport: rest dadl: /app/dadl/my-api.dadl url: "https://api.example.com" docs_url: "https://docs.example.com/authentication"6. Add coverage metadata
Section titled “6. Add coverage metadata”Helps users understand what the DADL file covers:
coverage: endpoints: 12 total_endpoints: 45 percentage: 27 focus: "items, users, search" missing: "billing, webhooks, admin" last_reviewed: "2026-03-29"7. Classify tools with access
Section titled “7. Classify tools with access”The optional access field on each tool enables role-based authorization. It tells policy files and OpenFGA what each tool does — without hard-coding tool names in policies.
Well-known values:
| Value | When to use |
|---|---|
read | Read-only operations — listing, searching, fetching details |
write | Creating or updating resources |
admin | Privileged operations — permissions, settings, configuration |
dangerous | Destructive or irreversible operations — deleting resources |
You can also use custom values for domain-specific needs (e.g. billing, pii, ops). ToolMesh passes them through unchanged.
tools: list_users: method: GET path: /users access: read description: "List all users"
export_user_data: method: GET path: /users/{id}/export access: pii description: "Export all personal data for a user"Best practice: Always set access explicitly. Don’t rely on HTTP method as a proxy — a POST /search is read, not write. A GET /admin/reset-cache is admin, not read.
Complete example
Section titled “Complete example”spec: "https://dadl.ai/spec/dadl-spec-v0.1.md"backend: name: my-api type: rest version: "1.0" description: "My API — items and users management"
auth: type: bearer credential: my_api_token inject_into: header header_name: Authorization prefix: "Bearer "
defaults: headers: Accept: application/json errors: format: json message_path: "$.message" retry_on: [429, 502, 503]
coverage: endpoints: 3 total_endpoints: 45 percentage: 7 focus: "items" last_reviewed: "2026-03-29"
setup: credential_steps: - "Go to https://example.com/settings/api" - "Create an API key with read/write scope" env_var: CREDENTIAL_MY_API_TOKEN backends_yaml: | - name: my-api transport: rest dadl: /app/dadl/my-api.dadl url: "https://api.example.com"
tools: list_items: method: GET path: /items access: read description: "List all items" get_item: method: GET path: /items/{id} access: read description: "Get item by ID" params: id: type: string in: path required: true create_item: method: POST path: /items access: write description: "Create a new item" params: name: type: string in: body required: trueNext steps
Section titled “Next steps”- Read the full DADL Specification for all available fields
- Browse the Registry for real-world examples
- Learn how to add composites for multi-step workflows