Skip to content

Install the AFP agent skill into your project with one command, then let the agent read this site as Markdown. The skill pins what a model cannot guess: AFP has no customer API, so what an agent produces is a campaign graph, not code; which node types the canvas can actually add; and which connections the canvas refuses. Every page here is also served as Markdown — append .md to any page URL — and /llms.txt indexes all of them.

  • An agent that loads instruction files from your project: a skills directory, or a rules file it reads at startup.
  • A campaign on the canvas to build the result in. An agent can describe a graph; only the canvas can save one. See Build a campaign on the canvas.

Download the skill from this site into your project:

Terminal window
mkdir -p .claude/skills/afp
curl -fsSL https://docs.afp.monster/skills/afp/SKILL.md -o .claude/skills/afp/SKILL.md

That path is where Claude Code looks for a project skill. An agent that reads a single rules or instructions file instead — Cursor and most editor assistants work that way — takes the same content: download it next to your other agent instructions and reference it from the file your tool loads at startup.

Terminal window
curl -fsSL https://docs.afp.monster/skills/afp/SKILL.md -o afp-skill.md

Commit the file so every contributor’s agent works from the same rules. The version field at the top records which AFP surface the file describes — re-download when that version changes.

The skill carries five things: the product model, every node type the canvas can add with its configuration keys, the connection rules the canvas enforces, one complete graph as a worked example, and a checklist of the mistakes models make about AFP.

Four surfaces, all generated from the same Markdown as the pages themselves.

URLWhat it holdsUse it for
https://docs.afp.monster/llms.txtAn index of every page with its descriptionLetting an agent choose what to read
https://docs.afp.monster/llms-full.txtThe full text of every page in one fileLoading the whole product in one fetch
https://docs.afp.monster/llms-small.txtThe same text with whitespace collapsedA smaller context window
Any page URL with .md appendedThat page as clean MarkdownReading one page without the navigation

The .md rule holds for every page, so an agent can build the address it needs from the address it is on: /reference/node-types becomes /reference/node-types.md.

A Markdown twin carries the page title, its description, and the body — no navigation, no sidebar, no scripts. The twins are served as text/markdown, cross-origin reads are allowed, and they are marked as not for indexing so they never compete with the pages they mirror.

Prefix each address with https://docs.afp.monster.

PageMarkdown address
Get started/start.md
Create your account/start/create-your-account.md
Connect a page/start/connect-a-page.md
Send your first auto-reply/start/first-auto-reply.md
Why is my campaign not replying?/start/troubleshooting.md
Build a campaign on the canvas/guides/build-a-campaign.md
Route comments to a DM/guides/route-comments-to-dm.md
Test and debug a campaign/guides/test-and-debug-campaigns.md
Match comments with keyword lists/guides/keyword-lists.md
Segment contacts with tags/guides/tags.md
Work with contacts/guides/contacts.md
Handle conversations in the inbox/guides/inbox.md
Moderate comments/guides/comment-moderation.md
Bulk-remove comments with the cleaner/guides/cleaner.md
Manage connected pages/guides/connected-pages.md
Manage profiles under one account/guides/profiles-and-master-accounts.md
Plans and billing/guides/plans-and-billing.md
Earn with referrals/guides/referrals.md
Get notified/guides/notifications.md
Get help/guides/support-tickets.md
Use AFP with AI coding agents (this page)/guides/ai-agent-skill.md
Node types/reference/node-types.md
Trigger events/reference/trigger-events.md
Keyword matching rules/reference/keyword-matching.md
Execution states/reference/execution-states.md
Campaign graph schema/reference/campaign-graph-schema.md
Contact fields/reference/contact-fields.md
Page permissions and tokens/reference/page-permissions.md
Plan quotas/reference/plans-and-quotas.md
Subscription lifecycle/reference/subscription-lifecycle.md
Notification catalogue/reference/notifications.md
Glossary/reference/glossary.md
AFP compared with the alternatives/compare.md
AFP vs ManyChat/compare/afp-vs-manychat.md
AFP vs Chatfuel/compare/afp-vs-chatfuel.md
AFP vs Meta’s built-in automations/compare/afp-vs-meta-automations.md
Changelog/changelog.md (coming soon)

An agent that cannot reach the network works from the same files offline: fetch /llms-full.txt once and commit it beside the skill.

Which campaign-graph patterns should the agent follow?

Section titled “Which campaign-graph patterns should the agent follow?”

Three shapes cover most of what people ask an agent to design. Each one satisfies the canvas rules, so it can be built node for node.

PatternNode orderUse it when
Keyword comment to DMtrigger_commentconditionreply_commentsend_dmstopA post asks people to comment a word to receive something
Reply and qualifytrigger_dmconditionsend_dmconditionadd_tagsend_dmstopAn incoming DM needs an answer and one follow-up question
Moderate and answertrigger_commentconditionhide_comment on Match, reply_comment on No MatchUnwanted comments get hidden and everything else gets a public answer

An agent describing a graph should name each node’s type and configuration keys and each connection’s source output. Those are the same names the saved graph uses — connections carry from_node_id, to_node_id, and output_index — so a described graph and a saved one can be compared field by field. Campaign graph schema has the full shape.

trigger_commentpost_scope allconditionkeyword_listreply_commentsend_dmstopstop Match, output 0 No Match, output 1

The public reply_comment before the send_dm is deliberate: it tells the commenter to check their messages, and other readers see that the page answers. Set the condition’s match_type to keyword_list and give it the identifier of a saved list; matching messages leave output 0 and everything else leaves output 1.

trigger_dmconditionmatch_type anysend_dmasks a questionconditionmatch_type containswait_for_replyadd_tagsend_dmstopsend_dmfallbackstop output 0 Match, output 0 No Match, output 1

A condition with wait_for_reply set parks the execution at that node until the person replies, and the reply is then matched the way a first message is — including the label of a button they tapped. Both branches need their own tail nodes, because a node accepts one incoming connection and two branches cannot merge.

A condition set to match_type: any matches everything and has a single output: the canvas drops its No Match output and removes any connection that left it. An agent that draws a No Match branch off an any condition is describing a graph the canvas will not keep.

trigger_commentconditionkeyword_listhide_commentstopreply_commentstop Match, output 0 No Match, output 1

Comment actions need a comment to act on, so this pattern only works under trigger_comment. Put the unwanted words in the keyword list and hide the Match branch, or set reverse_keywords on the condition so that everything the list does not match takes the Match branch instead.

  1. One trigger, and it is the only node with no incoming connection. Every other node has one, or activation fails.
  2. The trigger connects only to a condition, and a condition never connects to another condition.
  3. Each node takes one incoming connection, and each output handle carries one outgoing connection.
  4. No cycles. An execution that reaches a node it already visited ends with a cycle error.
  5. Comment actions are unavailable when the trigger is trigger_dm, and reply_comment and hide_comment are refused downstream of a delete_comment.
  6. On a condition, output 0 is Match and output 1 is No Match.

Campaign graph schema gives the exact field names and a full graph in JSON; Node types gives every configuration key an agent may write.

What models assumeWhat AFP doesWhat the skill gives the model instead
There is a REST API for creating campaignsThere is no customer API. Campaigns are authored on the canvas and saved from itAn instruction to say that, rather than write a request against an invented endpoint
A trigger can go straight to a send_dmA trigger connects only to a conditionThe connection rules, with this one named as the most common invalid graph
Any node type in the runtime can be usedOnly palette types have a settings panel, so only they can be configuredThe palette list, plus the type names never to use
Two branches can merge back into one nodeA node accepts one incoming connectionA rule to duplicate the tail instead of merging
Keywords are typed into the condition itselfA condition matches its own text, or references a keyword list you saved separately, by identifierThe four match types and which key each one reads
A plan’s campaign or page allowance is a fixed numberAllowances come from the plan on the accountAn instruction never to state a quota number
A DM can be sent to anyone at any timeThe first DM answers the event that started the execution; later messages reach the person’s account once they have repliedA note that platform messaging windows apply and AFP does not override them
Saving puts a campaign live, and editing changes runs in progressSaving writes a new version and activating is separate; a run stays on the version it started onBoth rules, next to the model
It is a chatbot builder, so “flow” and “bot” fitThe vocabulary is campaign, node, condition, executionThat vocabulary, used throughout

Two more the skill cannot fix on its own, because they only show up once a graph runs:

  • send_comment needs its own post_id. It does not fall back to the post the trigger fired on, and without one it does nothing when the execution reaches it.
  • One person cannot have two runs of the same campaign at once. While their run is active, a second matching event from them is skipped, so a follow-up message belongs behind a delay inside the same graph rather than relying on a second event from the same person.

How do I check the graph an agent gives me?

Section titled “How do I check the graph an agent gives me?”
  1. Build it on the canvas. The canvas validates while you drag, so a graph it cannot build fails at the first bad connection rather than after saving.
  2. Fix any node the canvas flags. Save campaign stays disabled while a node has a configuration error.
  3. Save, then run a test execution. It walks the saved graph and records what each node would have done, without messaging anyone, touching a comment, or changing a contact’s tags. See Test and debug a campaign.
  4. Activate only after the test path matches the agent’s description.

Why is the agent still producing a graph the canvas refuses?

Section titled “Why is the agent still producing a graph the canvas refuses?”
SymptomCauseFix
The agent writes code that posts to an AFP endpointThe skill is not loaded in this sessionConfirm the file is where the agent looks for instructions, then start a new session
The graph connects a trigger straight to an actionThe agent is designing from general chatbot knowledgeAsk it to restate the connection rules before proposing a graph again
The graph uses a node type with no settings panelThe node list came from somewhere other than the skillReplace it: a condition covers branching, a delay covers waiting
The agent quotes a campaign or page limitAllowances are plan configuration, not fixed valuesDrop the number and link Plan quotas instead
Two branches end at the same nodeFan-in reads well in a diagram, and the canvas refuses itDuplicate the tail nodes on each branch
The fields described do not exist in the settings panelThe skill predates a change to the surfaceRe-download the file and compare its version field
Tables from the site come back mangled, or nothing was fetchedThe agent read the HTML page, or has no network accessGive it the .md address or /llms-full.txt, or save those files into the repository beside the skill