# @agentforms/sdk
TypeScript SDK for AgentForms — programmatic form lifecycle for AI agents.
## Install
```bash
npm install @agentforms/sdk
```
## Quick Start
```typescript
import { AgentForms } from '@agentforms/sdk';
const af = new AgentForms('afk_live_...');
// Create a form
const form = await af.forms.create('Customer Feedback', [
{
name: 'rating',
label: 'Rating',
type: 'select',
options: ['1', '2', '3', '4', '5'],
required: true,
},
{ name: 'feedback', label: 'Feedback', type: 'textarea' },
]);
console.log(form.share_url); // https://agentforms.io/{token}
// Or generate with AI (Starter tier+)
const generatedForm = await af.forms.generate(
'Build a job application form for a restaurant'
);
// Read submissions
const subs = await af.submissions.list(form.token);
for (const sub of subs.submissions) {
console.log(sub.dynamic_data);
}
```
## Human-in-the-Loop Pattern
The core agent pattern: agent needs human input → creates form → sends link → waits for webhook.
```typescript
import { AgentForms } from '@agentforms/sdk';
const af = new AgentForms('afk_live_...');
// 1. Agent creates a decision gate
const form = await af.forms.create(
'Approval Request',
[
{
name: 'approved',
label: 'Do you approve?',
type: 'select',
options: ['Yes', 'No'],
required: true,
},
{ name: 'notes', label: 'Notes', type: 'textarea' },
],
{ session_id: 'conv_123', agent_turn: 7 } // metadata
);
// 2. Send the link to the human (via your messaging channel)
sendToUser(`Please review: ${form.share_url}`);
// 3. Webhook fires when submitted → your agent continues
// Webhook payload:
// { event: "submission", site_id: ..., fields: { approved: "Yes", notes: "..." } }
```
## Webhook Payload Schema
When a human submits a form, AgentForms POSTs to your configured webhook:
```json
{
"event": "submission",
"site_id": 42,
"site_name": "Approval Request",
"submission_id": 156,
"submitted_at": "2026-06-12T14:30:00Z",
"fields": {
"approved": "Yes",
"notes": "Looks good"
},
"field_metadata": {
"visible_fields": {...},
"computed_fields": {...},
"applied_conditions": []
}
}
```
## API Reference
| Method | Description |
|--------|-------------|
| `af.forms.create(name, fields)` | Create form with explicit fields |
| `af.forms.generate(prompt)` | AI generate form from prompt |
| `af.forms.get(token)` | Get form details |
| `af.forms.updateFields(token, fields)` | Replace all fields |
| `af.forms.delete(token)` | Delete form + submissions |
| `af.forms.list(limit, offset)` | List all forms |
| `af.forms.config(token)` | Get public form config |
| `af.submissions.list(token)` | List submissions for a form |
| `af.submissions.get(token, subId)` | Get single submission |
| `af.keys.create(name, permissions)` | Create API key |
| `af.keys.list()` | List API keys |
| `af.keys.revoke(keyId)` | Revoke API key |
## Error Handling
```typescript
import { AgentForms, AgentFormsError } from '@agentforms/sdk';
const af = new AgentForms('afk_live_...');
try {
const form = await af.forms.create('Test', []);
} catch (err) {
if (err instanceof AgentFormsError) {
console.error(`API error ${err.statusCode}: ${err.message}`);
}
}
```
## Configuration
```typescript
// Custom base URL and timeout
const af = new AgentForms('afk_live_...', {
baseURL: 'https://my-instance.agentforms.io/api/v2',
timeout: 60, // seconds
});
```
## Types
All public types are exported for use in your codebase:
```typescript
import type {
FieldDefinition,
Form,
Submission,
WebhookPayload,
ApiKey,
FormsResponse,
SubmissionsResponse,
Permission,
} from '@agentforms/sdk';
```