Agent API v1 · for resellers

You have the brands. We have the creators.

If you already reach founders, marketers or brands — a newsletter, an agency, a community, a client list — you hold the side of the market that's hard to get. We hold the other one: a network of real people who publish. Sell them a monthly presence in the conversations that matter, or a boost on a post they're proud of. One API key. The brand approves the wording before anyone posts.

Other way round — you have creators, not clients? That's the earning side →

Folded on purpose

Before you build

Four things worth knowing before you write a line. If you've already decided, skip to Set up once — nothing below is required to integrate.

The promise2 min

What each side of the market brings, and why neither works alone.

Attention is the expensive half of launching anything. Brands can build a product in a weekend and still can't get anyone to talk about it. Creators can publish to a real audience and have nothing worth publishing. ProductClank sits between them: a brief goes in, creators pick it up, and what they publish comes back as a link.

A storefront is a front door onto that. You already have the brands' trust — that's the part we can't buy. We already have the creators — that's the part you'd spend years building. The API connects the two so you never have to.

Why sell itwholesale

Margin, a product for an audience you already have, and nothing to fulfil.

  • You keep the spread. You buy credits at wholesale and sell at whatever your market bears. No revenue share, no platform fee on your sales, nothing to reconcile.
  • Nothing to fulfil. Finding the conversations, drafting, creator recruitment, fraud review, proof-of-post, payouts — all on our side of the API. Your job is selling, approving, and showing results.
  • It sells as a subscription. A brand's presence in its conversations is a monthly thing, and the cost per month is bounded. See Numbers.
  • Your brand end to end. Clients never see ProductClank or need an account here.
What to expecthonest

What a discovery subscription actually produces, how fast, and what it doesn't.

What we findLive conversations on X (or LinkedIn, Reddit, YouTube) where the brand's topic is being discussed — 5 per run, scored for relevance.
What we draftOne reply per conversation, in the brand's voice from the guidelines you set. The brand can edit any draft before it goes anywhere.
What creators doClaim an approved draft and post it from their own account — a real person, a real reply, in the thread.
When it startsDrafts are ready minutes after a run. Once published, creators pick them up on their own schedule — usually within hours.
What a result isA live link to the reply a named creator posted, plus the engagement it drew. Auto-delivered: it counts the moment it's posted — no review step in your way.
How manyUp to the drafts you publish. Creators choose what to pick up. Sell a presence, not a reply count.
What happens afterOur fraud review runs in the background. A reply it flags shows review_status: rejected on your results; one the platform removes shows survival_status. Both rare, both visible to you.
DisclosureEvery reply is marked as a paid partnership. Required, not optional.

See what the network is publishing right now on the live feed — every entry links to a real post.

What we commit to24h

The one number, and what we don't promise.

First creator response within 24 hours of publishing a draft. In practice you'll usually see the first one within minutes. If 24 hours pass with nothing, tell us — during the pilot we look at every one.
  • A run of discovery returns its drafts within minutes.
  • Results are readable the moment a creator posts. No approval step on our side.
  • Pilot support: a reply within the day on the thread we open with you.
  • Not promised: a number of posted replies. Discovery and drafting are charged when they run; a draft nobody picks up costs you nothing further, but it isn't refunded either. Price a presence, not a count, and your clients will never be surprised.
Once, ~10 minutes

Set up once

Three calls, or the web app (sign up → /credits → Profile → Developer) if you'd rather click. Same key either way.

Whose account it is. Everything runs under ONE ProductClank user — yours — with one key. No sub-accounts. Your clients' products are listed under you (public, idempotent per website). Every campaign is owned by your key, so the brand → campaign id mapping lives in your database only. Ignore caller_user_id and trusted — they're for first-party bots, and a normal key sending them gets 403.
1. Get a keyfree

Unauthenticated. Shown exactly once.

Register
curl -X POST https://api.productclank.com/api/v1/agents/register \
  -H "Content-Type: application/json" \
  -d '{ "name": "Acme Creator Studio", "description": "Storefront for Acme's clients" }'
The key starts pck_live_ and cannot be read back. Server-side secret only — never a browser bundle, client config or public repo. Leaked? POST /agents/rotate-key.
2. Fund itcard or crypto

The API hands you a Stripe Checkout link; a human pays it.

Get a checkout link
curl -X POST https://api.productclank.com/api/v1/agents/credits/topup \
  -H "Authorization: Bearer $PC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "bundle": "large", "payment_method": "card" }'

# → { "status": "awaiting_payment", "checkout_url": "https://checkout.stripe.com/…", "credits": 2600 }

Pay the link; credits land within seconds. The response is not a purchase — confirm with step 3. A monthly plan is usually the better buy for a subscription product; see Numbers. Keep a month of every live brand's ceiling on the balance — a run that lands on an empty account is a paying client waiting.

3. Verifyfree

Key works, balance is right, and your daily cap.

Who am I
curl https://api.productclank.com/api/v1/agents/me -H "Authorization: Bearer $PC_API_KEY"

# → { "agent": { "rate_limit_daily": 10, … }, "credits": { "balance": 2600, … } }

rate_limit_daily is 10 campaigns per key per day. One campaign per brand means it only bites when you onboard more than ten brands in a day — but send us your agent id and we raise it to 1,000 for the pilot anyway.

Product one · subscription

Discovery: a brand's presence in its conversations

One campaign per brand, created once. Every day you run discovery, the brand approves the drafts it likes, you publish them, and real people post. The brand sees every reply as it goes up. Five steps — three of them one call each.

1. Create the brand's campaign — once, held10 cr

Public campaign, private posts. Drafts arrive held until you publish them.

Create in held mode
curl -X POST https://api.productclank.com/api/v1/agents/campaigns \
  -H "Authorization: Bearer $PC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": "PRODUCT_ID",
    "title": "Acme — issue-tracker conversations",
    "keywords": ["issue tracker", "project management for small teams"],
    "search_context": "Founders and small teams comparing lightweight project tools",
    "platform": "twitter",
    "reply_guidelines": "Helpful, first-person, no hard sell. Mark every reply as a paid partnership.",
    "visibility": "public",
    "post_visibility": "private"
  }'

# → { "campaign": { "id": "CAMPAIGN_ID", … } }
This is the configuration that makes approval possible. The community only sees a post when both the campaign and the post are public. visibility: "public" opens the campaign; post_visibility: "private" keeps every discovered post held until you publish it. Omit the second and drafts go to the community the moment they're written — before the brand has seen them.

product_id comes from POST /agents/products {"url"} (free, idempotent). Put the disclosure requirement in reply_guidelines — it's a rule, not a suggestion. Store campaign.id against the brand.

2. Run discovery — daily, from your cron60 cr / run

Finds 5 conversations and drafts a reply for each. Two runs a day for a '10 a day' plan.

Generate
curl -X POST https://api.productclank.com/api/v1/agents/campaigns/CAMPAIGN_ID/generate-posts \
  -H "Authorization: Bearer $PC_API_KEY"

# → drafts land in GET …/posts with is_public: false (held)

A run is 5 posts at 12 credits each — sometimes fewer if the topic is quiet, and you pay only for what was found. Drafts are ready in minutes. Nothing is claimable yet.

3. The brand reviews — your UI, two callsfree

Show the drafts, let the brand rewrite any, and take note of which they approved.

Read the held drafts
curl "https://api.productclank.com/api/v1/agents/campaigns/CAMPAIGN_ID/posts" \
  -H "Authorization: Bearer $PC_API_KEY"

# → posts[]: { id, tweet_text, tweet_url, author_username, is_public: false,
#              CommuniplyReply: [{ id, reply_text, is_claimed: false }] }
The brand rewrote one
curl -X PATCH https://api.productclank.com/api/v1/agents/campaigns/CAMPAIGN_ID/replies/REPLY_ID \
  -H "Authorization: Bearer $PC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "reply_text": "We run a 3-person team on Acme — the keyboard-first flow is what stuck. Paid partnership." }'

The edit lands on the exact reply a creator will claim, so it is what gets posted. It refuses a reply that's already been claimed — which can only happen after step 4, so edit first, publish second.

4. Publish what they approvedfree

Releases only the posts you name. The rest stay held.

Publish
curl -X POST https://api.productclank.com/api/v1/agents/campaigns/CAMPAIGN_ID/publish \
  -H "Authorization: Bearer $PC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "post_ids": ["POST_ID_1", "POST_ID_2", "POST_ID_3"] }'

# → { "published": 3, "held_remaining": 2, "campaign": { "is_public": true, "is_active": true } }

From here creators can claim those three drafts. Each reply a creator actually posts bills you 20 credits, settled daily. Unpublished drafts cost nothing further. Don't use PATCH {visibility} for this — that flip releases every post in the campaign at once.

5. Show results — free, auto-deliveredfree

Live links as creators post. Poll it when the brand opens their page.

Activity
curl "https://api.productclank.com/api/v1/agents/campaigns/CAMPAIGN_ID/activity" \
  -H "Authorization: Bearer $PC_API_KEY"

# → { "claimed_replies": [ { "posted_url": "https://x.com/creator/status/…", "reply_text": "…",
#       "claimed_at": "…", "review_status": null, "survival_status": "alive",
#       "engagement": { "likes": 4, "replies": 1 } } ] }

Each posted_url is a result the moment it appears. posted_url: null means claimed, not yet posted. Free and read-only, so call it when a brand opens their page rather than on a schedule. To pause a brand, PATCH { is_active: false }; to cancel, leave it paused.

Product two · one post, one payment

Boost: amplify a post the brand already published

A brand pastes a post, picks replies or quote posts, pays you once, and creators respond in their own words. Auto-delivered, 200 credits, its own campaign per boost.

The whole flow200 cr

Confirm → pay → launch → results. Two of the four steps are yours.

Launch (after your payment confirms)
curl -X POST https://api.productclank.com/api/v1/agents/campaigns/boost \
  -H "Authorization: Bearer $PC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "post_url": "https://x.com/client/status/1234567890",
    "action_type": "quote",
    "reply_guidelines": "Genuine reactions only. Mark every post as a paid partnership."
  }'

# → { "campaign": { "id": "CAMPAIGN_ID", "action_type": "quote", … }, "items_expected": 10 }
  • Confirm first, no call: show the post, the action (replies or quote) and your price, get a yes. Boost has no preview endpoint yet.
  • Then take payment with your own processor. Only then launch.
  • Write campaign.id to the order immediately — it's returned exactly once. 402 holds the order; never fail it.
  • Results are the same /activity call as discovery. Slots drip out over ~24h and the campaign closes itself once they're gone — plan on 24–48 hours from launch.
  • Not /posts for results — it returns drafts without the published URL.
Three rules

Getting money right

Each exists because the alternative is a client who paid and got nothing, or paid once and you spent twice.

Charge the ceiling, once, up front. A discovery run costs 60 credits when it runs and up to 100 more as creators post — a known ceiling of 160 before you spend a credit. Price the subscription so the month's ceiling is covered on day one; then fill rate is margin, never loss. A boost is simply 200.
One payment, one launch — enforced by you. The API will create two boosts if you call it twice. Key launches on your payment provider's event id and make awaiting → launching a conditional update only one worker can win. For subscriptions the same rule applies to create: one campaign per brand, ever.
A 402 holds; it never fails. The client has paid. Park the run or the boost as “held — top up”, alert yourself, retry the same call when the balance is back. Credits are non-refundable once spent, so a client refund comes out of your margin. And if your provider's webhook can go missing, reconcile: ask the provider about any checkout that never came back.
Where each call lives

In your app

The steps above, placed in your system: which call runs on which event, what you persist, what state a brand is in, and what each error means. This is the section to hand to whoever wires it up.

Events → calls (discovery subscription)

Event in your appRuns onProductClank callYou persist
Brand subscribes (payment confirmed)webhookPOST /agents/products, then POST /agents/campaigns (held)brand: campaign_id, plan, status active
Daily, per active brandyour cronPOST …/{id}/generate-posts (×2 for '10 a day')run: campaign_id, ran_at, credits
Brand opens 'review drafts'your server, on requestGET …/{id}/posts (is_public:false = awaiting)nothing — render it
Brand edits a draftyour serverPATCH …/{id}/replies/{replyId}nothing — the API holds the text
Brand approves a setyour serverPOST …/{id}/publish { post_ids }approval log (optional)
Brand opens resultsyour server, on requestGET …/{id}/activitynothing — render it
Brand pauses / cancelswebhook or adminPATCH …/{id} { is_active: false }status paused
Run returned 402your cronretry the same call after top-uprun: held
Daily / on demandcron or dashboardGET /agents/credits/balancenothing — alert if low

Every call is server-side. The key never reaches a browser, and neither should the raw responses — map them to your own shapes. For a boost, the events are the four steps in the Boost section: confirm → pay (webhook) → launch → results.

The brand record

brands
id, client_email, product_url, pc_product_id,
pc_campaign_id,        -- from create; write it in the SAME transaction as the subscription
plan,                  -- e.g. "10/day" → runs_per_day = 2
status,                -- active | paused | held (credits) | cancelled
payment_ref,           -- your provider's subscription/event id — UNIQUE, this is your idempotency
created_at, last_run_at

What a draft is in, and what the brand sees

StateHow you knowBrand-facing
held/posts: is_public false“Awaiting your approval” — with edit
published/posts: is_public true; /activity: no claim yet“Waiting for a creator”
claimed/activity: claimed_at set, posted_url null“A creator is on it”
posted/activity: posted_url setThe link, with engagement
flagged / removed/activity: review_status rejected · survival_status removedHidden, or shown as such — your call; both are rare
Errors you will actually seehandle these

Six codes. Three are yours to fix, three mean wait or ask.

CodeMeansDo
402 insufficient_creditsBalance too low for this callHold it. Top up. Retry the same call.
429 rate_limit_exceededYour daily campaign-creation capOnboard the brand tomorrow — or send us your id for the raise.
400 confirmation_requiredPublishing a campaign that's still privateYou created it private by mistake. Publish with confirm:true — or recreate it held.
409 already_claimedEditing a reply a creator already tookToo late for that one. Edit before publish next time.
503 post_fetch_failedBoost only — we couldn't read the postRetry in a minute, or pass post_text and post_author.
400 validation_errorBad or unsupported URL / fieldShow the client; don't retry.

Anything else from a create or launch call: mark it failed, alert yourself, and don't retry blindly — a 500 after a successful create would double-spend. Check GET /agents/campaigns for a campaign you don't have an id for before creating again.

Your first test~$1

There is no sandbox. Here is the cheapest real run.

Create a held campaign for a product you own, run discovery once (60 credits — about a dollar at plan rates), read the drafts, edit one, publish one, and watch /activity. You've now exercised every call a subscription uses. Do it before you wire payments, so the first thing you debug is the API and not your webhook.

Price on top of these

Your numbers

Credits are your cost of goods. A monthly plan is roughly half the per-credit price of a bundle, and a subscription product should sit on one.

What a brand costs you per month

Plan you sellRuns / dayDiscovery (certain)Posted replies (≤)Ceiling / month
5 replies a day11,800 cr3,000 cr4,800 cr
10 replies a day23,600 cr6,000 cr9,600 cr

Plus 10 credits once per brand. The discovery column is charged when runs happen; the posted column accrues only as creators post — so a month lands between the two.

What credits cost you

BuyCreditsPricePer creditA 10/day brand at ceiling
Pro plan, monthly30,000$499$0.0166$160
Growth plan, monthly12,000$199$0.0166$160
enterprise bundle14,000$500$0.0357$343
large bundle2,600$100$0.0385$369

Reseller pricing on plans is available for the pilot — ask. Price your subscription against what the brand's alternative costs (an agency, a freelancer, ads), not against your credit cost — and never against a reply count you can't guarantee. A boost is 200 credits flat: $3–8 depending on how you buy.

Enforced on our side

Rules

The network is shared. One reseller's shortcut costs every creator on it.

  • Disclosure is mandatory. Require “paid partnership” in reply_guidelines on every campaign and boost. We audit.
  • Never sell likes or repost. The API accepts them; a reseller may not offer them. Bought engagement gets the creators' accounts penalised — the people doing the work, not your client.
  • Approved wording only. Held mode exists so a brand signs off before a real person puts their name to a reply. Don't publish drafts nobody has read.
  • No misrepresenting the network. Creators aren't your employees; don't invent follower counts; don't promise reply counts.
  • One key, one deployment. Violations end the account and forfeit remaining credits.
Third product

Coming next: content campaigns

Creators make original posts, threads or videos about a brand's product against a brief. Live in the API today, with one thing missing for a reseller — read the fold before you sell it.

Content campaigns via the API1000 cr

Free dry-run preview, launch, results — and why it's not in the first pass.

Submissions need approval, and there is no API for it yet. Creator submissions land as pending and count as delivered only once approved — today in ProductClank's web app, by you, per brand. Fine for a handful; not a storefront. A review endpoint comes after the discovery and boost passes are stable.
Preview — free, creates nothing
curl -X POST https://api.productclank.com/api/v1/agents/campaigns/content \
  -H "Authorization: Bearer $PC_API_KEY" -H "Content-Type: application/json" \
  -d '{ "product_id": "PRODUCT_ID", "campaign_message": "Show how you use it daily", "dry_run": true }'
# → { "proposal": { "title", "description", "action_message", … }, "credits_required": 1000 }
# Never forward this response to a browser: credits_available / can_afford are YOUR balance.
Launch, then results
curl -X POST https://api.productclank.com/api/v1/agents/campaigns/content … -d '{ …, "dry_run": false }'   # 1000 cr, runs 3 days
curl "https://api.productclank.com/api/v1/agents/campaigns/content/CAMPAIGN_ID?status=approved"           # free
# Use campaign.state (processing|active|ended…), never raw_status. Only "approved" is delivered work.
What we want from you

Piloting with us

A small number of partners before we open it up. You build against this page; we raise your daily cap, price your credits for reselling, and answer within the day; you tell us every place the page or the API let you down.

Send your agent id (GET /agents/me) and we raise rate_limit_daily.

Reference implementation. A complete, deployable storefront built on this flow — one config file, the order machine, dashboard, optional Stripe. Ask and we'll share the repo.

What to send back. Anything you had to guess, any shape you special-cased, any job that needed two endpoints, any number here that was wrong — and, above all, how many of your published drafts actually got posted. That number is the pilot. On the thread we opened, or hello@productclank.com.