Read this first
This guide is written for autonomous AI agents operating Puffle on behalf of a human customer. Use only the public endpoints documented under API Reference. Dashboard-only, admin-only, inbound webhook, OAuth callback, and private UI routes are intentionally outside this contract. Public product language uses Lead Finder, Feed, Outbound, Puffle Agent, Unibox, and Senders. API paths retain implementation names, so keep documented paths and request fields exact; there is no public/api/signals/planner/plan endpoint.
If something appears missing from the docs, it is either intentionally out of scope or a gap to report back to the human. Do not guess endpoints.
Authentication
Every public API call must include a Puffle API key as a Bearer token:- Keys are created by the human customer in the Puffle dashboard.
- Keys are scoped to a single workspace.
- Never log or echo the key back to the customer.
- On
401 unauthorized, stop and ask the human for a valid key.
pmcp_live_ key (or ChatGPT OAuth link) against Puffle MCP, not a pk_live_ API key. See Connect Puffle MCP.
Boot sequence
Before issuing workflow calls, read the workspace profile and context.Async and background work
Feed and Lead Finder runs and Outbound launches can dispatch background work. Follow the endpoint response and poll only a documented status endpoint with backoff. Recommended polling shape:- Start at 2 seconds.
- Double up to 30 seconds.
- Stop when the documented status becomes terminal, the operation returns a non-retryable error, or the user-defined time budget expires.
- Surface the
correlationId,runId, ortriggerRunIdwhen present so a human can investigate.
Error handling
The API Overview documents the current error shapes. Prefer structured errors when present:{ "error": "..." }. Use each endpoint page’s response examples as the source of truth.
Core user journeys
Journey 1 - Create and run a Lead Finder search
/api/feed routes for Feed work.
POST /api/lead-finder already reserves the first Run. Poll GET /api/lead-finder/{id}?limit=100&offset=0 until latestRun.status is completed, partial, or failed; queued and running are not terminal. Page through results using pagination.hasMore, limit, and offset. A partial Run can still contain usable results, but surface latestRun.errors before proposing outreach. A failed Run should not be retried unchanged.
Related docs: List Lead Finder Sources · Create Lead Finder Search · Run Lead Finder Searches · Get Lead Finder Search.
Journey 2 - Prepare Outbound from a Lead Finder search
/api/campaigns because Outbound drafts are campaign-backed.
- Finish paging through Lead Finder
results. Select only results the human has approved for outreach and whoseleaddata contains a usable email address for email Outbound or LinkedIn profile URL for LinkedIn Outbound. Map that identity to the exact campaign recipient field:emailorlinkedin_url. - Create the draft with
POST /api/campaigns. Creation does not add recipients. - Copy the reviewed contact fields into
POST /api/campaigns/{id}/leadsasprospects. This is the supported public preparation path; do not call the UI-only search-to-Outbound helper or assume results are linked automatically. - Check
importedandduplicates, then fetch every page ofGET /api/campaigns/{id}/leads?status=pending. Stop iftotalis zero or the roster differs from what the human approved. - Populate and review the sequence. Call
generate-messageswith the documentedresolveaction only after recipients and ordinary sequence content exist. Do not leave unresolved$ai {instruction}$slots; completing those slots requires a separate supported operation or human review in the dashboard. - Re-fetch the Outbound and sender state. Confirm
status: "draft", matching ready senders, at least one pending recipient, and non-empty content for every sendable node. - Present the human with the channel, sender identity, pending recipient count, and final sequence. Launch only after an explicit confirmation for that exact state.
- After
200, pollGET /api/campaigns/{id}every 30 seconds untilstatusbecomesactive. Do not re-launch while it islaunching. If launch returns400, surface and fix the blocker; on409, fetch current state before deciding what happened.
Journey 3 - Manage replies in Unibox
Journey 4 - Check sender readiness
Journey 5 - Review Posts
What agents MUST NOT do
- Do not call endpoints under
/api/admin/*. - Do not call inbound webhook receivers or internal integration callbacks.
- Do not call dashboard-only routes that are absent from the API Reference.
- Do not attempt OAuth or sender connection flows autonomously. They require a human-operated browser session.
- Do not persist the API key anywhere except in memory for the duration of the task.
- Do not ignore endpoint-specific rate limits or poll faster than endpoint guidance.
- Do not launch Outbound without explicit user approval.
Escalation
Stop and ask the human when:- The requested action requires OAuth, login, sender/domain setup, or another browser interaction.
- A route returns
403,404, or an unexpected409. - A
500 internal_errorpersists after one retry. - The requested outcome has no corresponding endpoint documented here.