# Influensia > Collaborative link-building and creator marketplace: buyers (clients) order > verified editorial/guest-post/niche-edit placements and channel posts from > sellers (providers), with escrow, third-party metric verification, > in-thread offers and analytics. ## API - OpenAPI 3.1 (contract of record): /api/v1/openapi.json - Interactive docs: /docs - Developer guide (auth, conventions, client setup, worked examples): /docs/agents - Auth: `x-api-key: flu_…` header (create a key in workspace settings) or a session Bearer token. Select a workspace with `X-Workspace: `. - Errors: RFC 9457 application/problem+json. Rate limit 240 req/min per credential; 429 responses carry Retry-After (seconds). - All POSTs accept an Idempotency-Key header (24h replay window) — always send one for order requests. - Lists paginate by cursor (`cursor`, `limit` ≤ 100); ids are time-ordered uuidv7, so cursors sort chronologically. ## MCP - Endpoint: /api/mcp/mcp (Streamable HTTP) - Auth: `Authorization: Bearer flu_…` (API key) - Connection recipes (Claude Code, claude.ai connectors, the Claude API MCP connector, Agent SDK): /docs/agents - Your roster is per WORKSPACE KIND. A buying workspace is served the buy-side tools, a selling one the sell-side, and the shared tools appear in both. Everything is listed below so both sides are documented, but a tool missing from your own tools/list is one your workspace cannot call — not an outage. `whoami` says which side you are on. - Tools (108, task-level): - account: whoami, get_billing_summary, list_billing_history, get_rewards_summary, redeem_reward, tip_post, tip_comment, get_my_profile, update_my_profile, get_notification_prefs, update_notification_prefs - buying: get_market, find_domains, compare_domain_offers, find_channels, get_channel, get_member_profile, request_order, get_order_status, list_orders, list_order_items, cancel_order, advance_order_item, set_order_item_brief, set_auto_release, get_basket, add_basket_item, set_basket_item_brief, set_basket_campaign, remove_basket_item, clear_basket, list_reviewable_orders, write_review - selling: draft_order_item, list_my_markets, list_market_inventory, add_listing, update_listing, update_market, publish_market, import_inventory, get_import, list_import_rows, update_import_row, confirm_import_mapping, commit_import, list_imports, resync_market, remove_market, restore_market, list_my_channels, claim_channel, check_channel_claim, refresh_channel, archive_channel, restore_channel, list_channel_offers, add_channel_offer, update_channel_offer, remove_channel_offer, preview_channel_roster, commit_channel_roster, reply_to_review, refresh_domain_metrics, get_metrics_status - messaging: list_conversations, read_conversation, open_conversation, send_message - work: list_projects, get_project_health, create_project, update_project, remove_project, list_campaigns, create_campaign, update_campaign, remove_campaign, get_campaign_report, get_campaign_insights, recommend_placements, add_campaign_placements, create_document, list_documents, get_document, update_document, publish_article, list_my_articles, get_article, update_article, unpublish_article, create_feed_post, list_feed, list_briefs, publish_brief - team: list_workspace_members, list_invitations, invite_member, list_access, share_access, revoke_access_grant - insight: get_analytics_summary, get_analytics_insights, search, check_link_health, request_link_recheck, list_notifications, mark_notifications_read - Briefs: the DEMAND side. A buyer publishes what a campaign needs (publish_brief, confirm-mode — it is externally visible) and sellers answer with a priced offer. list_briefs is the seller's board; pass matchingMyInventory to see only what your live listings could fill. A brief never carries the client's name or the website the links point at, and an anonymous one carries no buyer either. ANSWERING a brief has no tool on purpose: an agent that mass-answered them would be spam, so the offer is composed by a human in the web app. - Selling inventory: a market is BORN from an import — import_inventory with a link-viewable Google Sheet, poll get_import, confirm_import_mapping when it reaches `mapping`, check flagged rows with list_import_rows / update_import_row, then commit_import with a `name` (new draft market) or a `targetMarketId` (append to one you own). CSV / XLSX / PDF price lists are uploaded in the web app; an agent surface cannot send a file, so a sheet link is the agent's route in. After that the market is yours to run: list_market_inventory to read it, add_listing / update_listing per domain, update_market to rename or unpublish, publish_market to put it on sale (confirm-mode, refused with no listings), resync_market to re-read the sheet, remove_market and restore_market to retire or revive it. Nothing deletes a listing anywhere on the platform — `available: false` pauses it, because deleting would break the offer's history and orphan a buyer mid-negotiation. Imports read the FULL provider vocabulary: per-vertical price columns ("Casino Price", "Crypto Price" — a money cell = accepted at that price, "No" = refused; one "Gambling" column feeds betting AND casino), link terms ("Links Type" = do-follow/no-follow, "Sponsored", "Duration" — permanent/6/12/24/36 months, "Samples Posts"), content terms ("Price per word", "Max words", "Languages"), the quality metrics buyers screen on ("Referring domains", "Spam score", "Organic keywords", "Traffic value") and the SITE's own "Language" — which is NOT the writing languages above, and feeds the language facet find_domains filters by. They land on the listing as terms + nichePrices, editable per row before commit (update_import_row `terms` / `nichePrices`, full-replace each), and a sheet-sourced market's nightly re-sync follows the same columns — seller hand-edits always win. Most sheets price only the PLACEMENT, so commit_import takes `contentDefaults` — one set of writing terms (contentPricePerWord, wordTiers, wordsMax, contentLanguages) for every domain in the import. Without a per-word rate a listing sells "buyer's content only" and the buyer's content-requirements options do not exist, so an import that skips this produces a market that cannot sell the writing its seller sells. The defaults fill silence only, and the re-sync re-applies them to domains the sheet adds later. `placementDefault` answers the other thing most sheets leave out: what the price BUYS. A row with its own placement column keeps it; everything else takes the import's default, which is what the sheet implied (a lone "Guest post price" column says guest post) and otherwise a guest post. Read `stats.placementDefault` from get_import before overriding it, and remember an offer's identity is (market, domain, placement) — a different answer creates a different listing, it does not re-price one. - Buying paths: request_order proposes ONE seller's order directly. The BASKET is the multi-seller path — add_basket_item / set_basket_item_brief build a shared workspace shortlist that checkout splits into one order per (market, campaign) atomically. Either way a human pays: there is no checkout tool. Every link line needs its brief before checkout will take it. - Team & access: full members see the whole workspace; GUESTS see nothing until a grant reaches them. share_access is the single write (a project, campaign or order to one person, by userId or email — an unknown address gets a guest invitation carrying the grant), list_access shows who reaches what and whether that reach is inherited from a parent project, and invite_member / update_member_role / remove_member run the roster. Money verbs — fund, release, cancel, dispute — stay full-member-only whatever a grant says. - Reviews: a released order can be reviewed ONCE, publicly and permanently (write_review), and the seller answers ONCE and never edits (reply_to_review). Neither can be deleted; both feed the derived trust stats other tools report. - Campaign supply: recommend_placements answers "what should this campaign buy next" from the campaign's own guardrails — prefer it over find_domains, which searches the whole directory and knows nothing about the campaign. add_campaign_placements shortlists domains as prospects (no money, no order); a prospect is replaced by the real row when it is later bought. Guardrails themselves are set with update_campaign. - AI insights: get_campaign_insights reads one campaign, get_analytics_insights reads the workspace's reporting for a window you choose (`months`, or `from`/`to`, plus the same scope arguments as get_analytics_summary). Both are PRO — `state` says locked/unavailable otherwise, and a human upgrades in the web app. Every insight cites the derived signal keys behind it and anything uncited is dropped, so neither states a fact the platform did not measure: no competitor data, brand mentions, indexation, rankings, or what other sellers charge. Use them for "what should I do"; use get_campaign_report / get_analytics_summary for the numbers themselves. - Projects are METERED, unlike everything else here. A project is one website, and adding one buys that domain's authority/backlink baseline on the platform's account — so the plan caps how many a workspace holds: Free 1, Pro 10. ARCHIVED projects count (they still hold their domain), and on Free remove_project archives rather than erases, so nothing you can call hands a slot back. create_project answers 409 when the allowance is spent. When that happens there are exactly two real moves: update_project to re-point an existing website's `site` (allowed until it has campaigns, costs no slot), or tell the user to upgrade in Settings → Billing. Retrying, or removing something first and creating again, will not work — do not loop on it. - Campaigns: pass `campaignId` to request_order to buy links FOR a campaign. An order's campaign is set when the order is created and can never be attached afterwards, so an order requested without one is a loose purchase that no campaign board will ever show. When the user's intent names a campaign, carry the id through — call list_campaigns first if you need it. - Safety: request_order creates a PENDING request; a human pays through checkout (POST /api/v1/billing/checkout), approves drafts and releases per-link escrow. Agents propose, humans pay; cancel_order un-proposes before money moves. Providers' agents may draft placement content (draft_order_item) and walk a placement through its lifecycle (advance_order_item), but every money step stays human-only: releasing escrow has no tool. `mark_live` is the one to be careful with — it is the claim that the agreed link is published, the checker judges the URL against the brief, and under the buyer's auto-release policy a verified live link releases its own escrow. Call it from a URL you have confirmed, never from a draft being finished. publish_article is confirm-mode and DRAFTS by default: words published under someone's byline stay there, so an agent writes and a human decides whether it goes out. There are no tools that pay, subscribe, manage cards or touch payout accounts — deliberately. - What confirm-mode means FOR YOU: in the in-app assistant, a confirm-mode call parks until a human approves it in-chat. Over MCP there is no such pause — your API key is the user's standing consent and every tool, confirm-mode included, executes immediately. So for the cost-bearing ones (redeem_reward spends a scarce balance with no refunds; refresh_domain_metrics spends the seller's OWN third-party API budget, ~150 Ahrefs units per domain; refresh_channel buys a vendor read, once a day per channel; check_channel_claim burns one of six checks that a channel EVER gets before verification closes for good) the rule is: call them only when the user explicitly asked for that spend, never speculatively. Connecting or replacing a provider key has no tool at all — credential management stays in the web app, like API keys and 2FA. - Credits & quests: get_rewards_summary is the user's quest standing — balance, badges, and every quest with an `href` for where the work happens. Credits are platform-internal (no cash value; the one transfer between members is a tip — tip_post / tip_comment, capped) and awards are server-verified facts, reconciled when the summary is read. There is no earning tool to call directly: existing verbs earn (refresh_domain_metrics feeds Registry medic, publish_article feeds Voice). redeem_reward SPENDS the balance (no refunds — see "What confirm-mode means" above: over MCP it executes immediately, so only on an explicit user ask): pro_month 1,000 · fee_voucher 500 · market_boost 300 (marketSlug required). tip_post and tip_comment SPEND too (1–500 credits to the author, 250/day out across BOTH — one budget, not two — and no undo; same explicit-ask rule). Credits never touch money — a Stripe-subscribed workspace refuses pro_month. - Channels: sellers also list verified social channels (YouTube, Instagram, TikTok, X) with priced formats — posts, Reels, videos, threads — next to their link inventory. find_channels browses the catalog; get_channel returns every seller's offer on one channel. Identity is (platform, handle), because the same channel is sold by its creator AND by talent managers. Audience numbers (followers, engagement, average views) are platform-sourced projections refreshed on a schedule, never self-reported, and every listed channel passed a one-time bio-code ownership check. `trend` follows the domain rule above: +1/-1 only once two of our own readings show a move over 2%, `null` otherwise — unmeasured, not flat. Channel placements ride the SAME order lifecycle and per-item escrow as links — one order can mix both kinds — but their delivery proof is the post's platform stats, not a link check. Order them with creatorOfferIds (from get_channel) on request_order or POST /orders. - Selling channels: the seller's side of the same thing. claim_channel mints a one-time bio code, A HUMAN puts it in the bio, then check_channel_claim proves control — and that check is RATIONED: three failures pause verification for a week, three more close it permanently, so never call it speculatively. Only a verified claim can be listed: add_channel_offer prices one (channel, format), update_channel_offer re-prices or pauses it, remove_channel_offer deletes one nothing has ordered. In bulk, preview_channel_roster dry-runs a sheet and commit_channel_roster files the claims and prices the formats (already-verified handles go live at once). refresh_channel buys one look a day at a channel's public numbers, on the PLATFORM's vendor budget rather than the seller's own keys. archive_channel / restore_channel retire and revive a channel; nothing deletes a claim, because it carries the verification ledger. - Domain metrics: sellers connect their own Ahrefs / Moz / Majestic keys, and a background refresh writes VERIFIED metrics onto the canonical domain registry. Only connected providers contribute, and metrics are never substituted across them — Domain Rating (Ahrefs), Domain Authority (Moz) and Trust Flow (Majestic) are separate indexes, so a seller with one key gets that provider's numbers and nulls elsewhere. `verifiedBy` on a domain names exactly who contributed. Empty is "we don't know", never zero. - Link verification: every purchased placement is fetched and checked against what was ordered — link present, right target page, right anchor, not nofollowed — on marking live and then on a widening schedule (1, 3, 7, 30, then every 90 days). check_link_health reports it. "What was ordered" is the item's brief: buyers set it with set_order_item_brief (anchor + target page + content guidance), ideally before production starts; without one the placement can never verify. The brief freezes when the link goes live. Three states, and the difference matters when you report them: `verified` (we saw the link), `failed` (we fetched the page and the link was wrong or gone — real evidence), `pending` (never checked, or we could not reach the page — NOT a problem, and never to be reported as a broken link). check_link_health also carries Google indexation per placement (`indexStatus`): `indexed` (seen in Google, with `indexedAt` as the badge date) or `unknown` — which covers "not checked yet" AND "not seen in a SERP sample". Advisory only: it never affects escrow, and `unknown` must never be reported as "not indexed" — the platform itself refuses to draw that conclusion without Search Console evidence. ## Start here 1. GET /api/v1/me (MCP: whoami) — confirm your credential, active workspace and workspace role before anything else. GET /api/v1/me/profile (MCP: get_my_profile) is the public half (headline, location, bio, services, niches), addressed by credential so it answers before a handle exists; PATCH the same path (MCP: update_my_profile) to change it. Read before writing: a member edits these same fields in their settings, and a patch replaces a field, not merges it. 2. GET /api/v1/markets — browse; GET /api/v1/markets/{slug} for inventory. GET /api/v1/domains (MCP: find_domains) filters the whole directory — and for content in a priced vertical, pass placementNiche: only domains with an offer ACCEPTING it match, every price in the response becomes that vertical's own variant price, and facets.acceptedNiches/linkTerms say where else you could go. linkType / sponsored / permanentOnly filter the sold link terms. 3. GET /api/v1/domains/{name} — compare every provider's offer for one domain (same name, different sellers/prices/delivery), cheapest first. METRICS ARE THE DOMAIN'S, NOT THE OFFER'S: dr, da, traffic, refDomains, spamScore and organicKeywords are identical on every offer for a site, read from the shared registry when any seller's connected provider has checked it and from the selling seller's claim only while nobody has. `verified` says which, `verifiedBy` names the providers and `metricsCheckedAt` says when. Two fields sit outside that rule, in opposite directions. `trafficValue`: no provider exposes it, so it is always a seller claim. `trend` (+1 rising / -1 declining): nobody can claim it, because a direction asserts movement over time — it is derived from two of our own monthly readings, and `null` whenever we have not measured one, which is the common case. Null means unmeasured, not flat. Compare offers on price, delivery, link terms and content terms; comparing their metrics is comparing a site to itself. Each offer carries that SELLER's own content terms — per-word rate, word tiers/cap, writing languages; null rate = buyer-written content only — plus its own link terms and niche pricing: `dofollow`, `sponsoredLabel`, `durationMonths` (null = permanent) and `nichePrices`, the verticals (betting/casino/forex/crypto/cbd/loans/adult/grey) THIS seller accepts, each at its own price; a vertical absent from the list is refused, never priced at base. Terms are per offer, never merged across sellers, and a seller's writing languages are not the site's audience language. 4. GET /api/v1/users/{handle} — vet the seller (verification, live stats, reviews) before spending. GET /api/v1/users/verified?ids=a,b,c is the batch form of the identity question alone: a map of user id to boolean, max 100 ids, unknown ids read false. It answers for the PERSON; the workspace-level Verified business badge travels on market and offer payloads as `sellerVerified`, list shapes included — filter a browse on it without a detail call per market. 5. POST /api/v1/orders {marketId, domainIds, creatorOfferIds?, briefs} + Idempotency-Key — one order can mix link and channel placements from the same market. Every LINK placement requires its brief in `briefs` (keyed by domainId): the anchor text is mandatory, and the target page may be omitted only when campaignId names a campaign with a site. The brief also carries the content choice: contentMode "seller" (only on listings with a per-word rate; requires contentWords from the listing's tiers/cap) prices words × rate INTO the item and the publisher writes; the default "buyer" means you supply the draft and the publisher approves it — the item's draft document exists from creation, and start/submit_draft are YOUR verbs on such items. The brief also names the placement niche: default "standard" (the listing's base price); a priced vertical from the listing's own nichePrices re-prices the item from THAT variant, and a vertical the listing doesn't accept refuses the order naming it. The item snapshots the listing's dofollow/sponsoredLabel/duration terms at creation — what verification later judges the live link against. The MCP request_order takes the same brief inline per domain. 6. GET /api/v1/conversations — the deal thread lives here 7. GET /api/v1/projects/{id}/campaigns then /api/v1/campaigns/{id} — how existing campaign work is performing