Skip to main content

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.
See API Overview authentication and API key management. MCP clients use a different integration: a 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.
Use this to understand the company, ICP, target market, differentiators, and current setup before planning or changing anything. If context is missing or clearly wrong, ask the human to update the Company settings before running Feed or Lead Finder searches or preparing Outbound.

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:
  1. Start at 2 seconds.
  2. Double up to 30 seconds.
  3. Stop when the documented status becomes terminal, the operation returns a non-retryable error, or the user-defined time budget expires.
  4. Surface the correlationId, runId, or triggerRunId when present so a human can investigate.
Do not busy-loop. Do not poll more than once per second.

Error handling

The API Overview documents the current error shapes. Prefer structured errors when present:
Some route-specific errors still return a flat shape such as { "error": "..." }. Use each endpoint page’s response examples as the source of truth.

Core user journeys

Use this when the user asks for a new Lead Finder search or wants to refresh an existing one. Discover the executable source catalog first, create the search with an explicit source configuration, and then run it. Updating a search changes future runs; it does not rewrite prior results. Use the matching /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.
Use this when Lead Finder results are strong enough for outreach. The API path uses /api/campaigns because Outbound drafts are campaign-backed.
  1. Finish paging through Lead Finder results. Select only results the human has approved for outreach and whose lead data contains a usable email address for email Outbound or LinkedIn profile URL for LinkedIn Outbound. Map that identity to the exact campaign recipient field: email or linkedin_url.
  2. Create the draft with POST /api/campaigns. Creation does not add recipients.
  3. Copy the reviewed contact fields into POST /api/campaigns/{id}/leads as prospects. This is the supported public preparation path; do not call the UI-only search-to-Outbound helper or assume results are linked automatically.
  4. Check imported and duplicates, then fetch every page of GET /api/campaigns/{id}/leads?status=pending. Stop if total is zero or the roster differs from what the human approved.
  5. Populate and review the sequence. Call generate-messages with the documented resolve action 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.
  6. 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.
  7. Present the human with the channel, sender identity, pending recipient count, and final sequence. Launch only after an explicit confirmation for that exact state.
  8. After 200, poll GET /api/campaigns/{id} every 30 seconds until status becomes active. Do not re-launch while it is launching. If launch returns 400, surface and fix the blocker; on 409, fetch current state before deciding what happened.
Related docs: Get Lead Finder Search · Create Outbound Draft · Add Recipients · Review Recipients · Generate Outbound Messages · Launch Outbound.

Journey 3 - Manage replies in Unibox

Use Unibox after replies arrive or when the human asks you to inspect ongoing conversations. If a thread requires a sender account that is not connected, direct the human to complete that setup in the dashboard. Related docs: Unibox · List Threads · Send Thread Message.

Journey 4 - Check sender readiness

Use this before preparing or launching Outbound. Sender setup can require human-owned inbox/domain steps that agents should not fake or bypass. Related docs: List Senders · Email Accounts · Email Domains.

Journey 5 - Review Posts

Use this when the human asks to inspect LinkedIn or X posts. The human chooses the account, media, schedule, and publish action in Posts. Related docs: List Posts · Get Post · List Social Accounts.

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 unexpected 409.
  • A 500 internal_error persists after one retry.
  • The requested outcome has no corresponding endpoint documented here.