Use casesPricingMCPStatus
Sign in
For agents

Instructions

Read this before your first call. It is written for you, not for the person who gave you the key.

Updated August 28, 2026

What Adveron is

An advertising and marketing intelligence API. It answers questions about brands, categories, audiences, and creative across social and ad platforms — what competitors are running, how a market is talking, who an audience listens to — and it carries an agent OS layer (context, memory, activity) so you can work for the same business over weeks rather than one conversation.

The surface is REST. Reads are GET — the resource id rides the URL (https://api.adveron.com/v1/brands/{id}), filters and paging ride the query string (?limit=&cursor=). Writes and the analysis actions that compute a derivative are POST / PUT / PATCH / DELETE, taking a JSON body. Successful responses are { "data": …, "meta": … }; failures are { "error": { "code", "message", "request_id" } } with an honest HTTP status. A metered read answers Cache-Control: no-store.

Get oriented in 60 seconds

  1. Authenticate. Send Authorization: Bearer adveron_… on every request, plus Content-Type: application/json. The key is workspace-scoped: it decides whose data you see, whose credits you spend, and — via its name — which memory and activity are yours.
  2. Learn who you work for. Call GET /v1/context first. It returns the workspace’s standing brief, and it is free. Read the slots that matter before you decide anything.
  3. Check what you can spend. GET /v1/balance returns total_spendable, the pools behind it, and overage_debt. Do this before a plan that involves many live lookups.
  4. Check what has already been done. GET /v1/memory/entries for your own notes from previous sessions, GET /v1/activities for what every agent in the workspace reported. Both free. Repeating last week’s analysis is the most common way to waste a run.
  5. Keep this page. GET /v1/instructions (MCP: instructions_get) serves the same contract as markdown, with an updated_at date, free and without a browser — this page and that document are two renderings of one set of rules, not two sources. Call it when you start new work and refresh whatever skill or saved instructions you keep whenever the date has moved.
  6. Go deeper when you need to. Full reference at adveron.com/docs, machine-readable spec at adveron.com/openapi.json, the short version of this page at adveron.com/llms.txt, and an MCP endpoint at https://mcp.adveron.com if your host speaks MCP instead of HTTP.

The first call

GET https://api.adveron.com/v1/context · Authorization: Bearer adveron_…
{
"data": {
"items": [
{ "slug": "brand_product", "kind": "BRAND_PRODUCT", "label": "Brand & product", "title": "Brand & product", "written": true, "source": "MANUAL", "updated_at": "2026-08-14T09:12:04Z", "updated_by": "ana@northwind.com" },
{ "slug": "marketing_strategy", "kind": "MARKETING_STRATEGY", "label": "Marketing strategy", "title": "2026 growth plan", "written": true, "source": "AGENT", "updated_at": "2026-08-14T09:20:41Z", "updated_by": "research-agent" },
{ "slug": "competitor_analysis", "kind": "COMPETITOR_ANALYSIS", "label": "Competitor analysis", "title": "Competitor analysis", "written": false, "source": null, "updated_at": null, "updated_by": null }
]
},
"meta": { "request_id": "req_…", "total": 5 }
}

Two modes of data access

This is the distinction to get right, and it is the one that produces most confused agents. Adveron answers live questions about anything, and ongoing questions only about entities your organization has activated. Deciding which mode a task needs is your job, not the API’s.

Mode 1 — live search. No setup, costs credits.

Use it when the question is “what is happening right now” or “who is this”: a one-off lookup, a name you have never seen before, a URL somebody pasted. Nothing has to be activated; every call spends credits because it spends a vendor call.

discover.posts
Posts matching q on one platform (x, instagram, tiktok, linkedin, facebook, youtube, reddit). Narrow with since (hour…year) and sort.
discover.ads
Ad libraries: platform is meta, google, or linkedin. For google, q must be the advertiser’s domain (nike.com), not its name.
discover.communities
Communities discussing a query — where a conversation lives.
discover.jobs
Job postings matching a query: a hiring and expansion signal.
enrichment.profile.*
get, posts, following, search for a creator or account you can already name.
enrichment.company.*
search to resolve a name to a handle, then get, jobs, people, posts.
enrichment.post.*
lookup a URL, get the post, then comments and reactors for the reaction to it.
enrichment.video.transcript
The spoken text of a video, by its {id} (the MCP tool argument is video_id).

Catalog browse is open too, and free: brand.search, category.list, category.get, audience.list (with q to search by name). Use them to turn a name into an id before anything else — every other brand, category, and audience operation takes an id, never a name.

Mode 2 — tracked entities. Requires activation, reads are free.

Anything ongoing runs here: a competitor dashboard, a daily feed of a rival’s creative, share of voice over twelve months, an opportunity tracker. Adveron collects these entities continuously and keeps the history, which is why the entity has to be activated — an activation is a slot on your organization’s subscription, held at the org and shared by every workspace in it. Reads against an activated entity spend no credits; the slot already paid for them.

brand.overview · brand.get
The current state of one tracked brand.
brand.paid_media.ads.list
Ads that brand is running, with status (ACTIVE / ENDED), platform, start_date, days_running, and the creative analysis (hook, angle, tone, offers). Siblings: ads.get, summary, and crawl-coverage — per day and per platform, whether we looked at all, so a day with no new ads is legible as “nothing launched” rather than “we didn’t look”.
brand.owned_media.*
What the brand publishes itself: posts.list, posts.get, summary.
brand.executives.* · brand.executive_media.*
What the brand’s leadership publishes on their own profiles: executives.list, executives.get, and the media itself (posts.list, posts.get, summary). Its own dataset — executive voice never enters the brand’s owned-media counts.
brand.mentions.*
What other people say: list, get, and summary (themes and sentiment, filterable by platform, region, sentiment).
brand.love_letters · brand.customer_complaints
The same mentions grouped by aspect — what the sentiment is about — at fixed polarity, each with a frequency, a dominant intensity, example posts and source link-backs. All time by default; same filters as mentions.list minus sentiment.
brand.timeseries
A metric over time: dataset, metric (e.g. mention_volume, ad_count, net_sentiment), grain (day/week/month), window (7d…1y).dataset is required for the follower metrics and refused for the rest.
brand.compare · brand.competitive_set · brand.benchmark
One brand against its rivals; every brand named must be activated.
brand.creative_patterns · category.creative_patterns
The hook and angle frames being run, as a leaderboard — one brand's, or a whole category's. Both take window (7d/30d/90d) and publish the same shape, so the two read side by side. Frames come from a fixed vocabulary, which is what makes the counts comparable.
category.trends · category.news · category.landscape · category.brands · category.whitespace
Market-level reads keyed by category_id. category.trends returns trend, volume, momentum, sentiment — with the window the volume covers echoed once as data.window.
audience.insights · audience.posts · audience.brands · audience.influencers · audience.subreddits · audience.podcasts · audience.substacks
Who a segment is and what it consumes, keyed by audience_id. audience.insights returns top_brands, top_themes, top_content.
audience.conversations · audience.triggers · audience.objections · audience.awareness_map
What a segment talks about, from the stored weekly theme refresh: every theme, the ones that move it toward buying, the ones it pushes back in, and the whole set mapped onto awareness stages. Each theme keeps a stable theme_id across refreshes, and meta.set_version is null until the audience has been clustered.
evidence.search
Free and unlimited, like the other index-side reads. Semantic search by q across your activated audiences’ posts, mentions of your brands and your brands’ owned media at once — ranked by meaning, not by matching words, so it finds a conversation you can describe but cannot spell. Each result reports the corpus it came from. Top-K only: raise limit rather than looking for a next page.

What to do about a 403 resource_not_activated

An unactivated entity refuses with HTTP 403 and "code": "resource_not_activated" before anything runs and before anything is charged. This is not a transient failure and not an authentication problem.

  • Do not retry, and do not try the same id through a different operation — the same gate sits in front of all of them.
  • Tell your human exactly what to activate. Name the resource type and the id you got from brand.search / category.list / audience.list, along with the display name. An organization admin activates it in the console at app.adveron.com; the picks it already holds are listed under Tracking.
  • Do not silently substitute live search for a tracked job. A one-off discover.ads query is a fine stopgap answer for today, and you should say that is what it is — it has no history behind it, so it cannot become the daily feed that was asked for.
  • Write the blocked request down (memory.write) so the next run picks it up once the slot exists, instead of rediscovering the 403.

The OS layer: context, memory, activity

Three free operation families that turn a stateless call into durable work. None of them costs credits, deliberately — an agent that has to budget for reading its brief stops reading it.

Context — the standing brief, shared by the workspace

  • context.list always returns the five built-in slots — brand_product, marketing_strategy, competitor_analysis, brand_voice, content_strategy — whether or not anybody has filled them. "written": false means the slug is real and empty, so writing to it fills the slot rather than inventing a document.
  • context.get takes the slug and returns the markdown. A slot listed as unwritten answers not found.
  • context.write replaces the whole document. It is not an append: send the complete markdown, or what you leave out is gone. A slug of your own also needs a title. Previous versions are kept, and the write is attributed to you.
  • Read context before you act. Write back what you learned about the business — positioning, a competitor set that turned out to be wrong, the voice rules you inferred — not the raw data you learned it from.

Memory — your own filesystem, namespaced by your key's name

  • Paths are forward-slash, no leading slash, no .. segments: watchlists/competitors.md. Folders are created for you.
  • memory.write replaces a file whole; memory.edit replaces one exact snippet (old_text must match character for character and be unique unless you pass replace_all); memory.list, memory.read, memory.move, memory.mkdir, memory.delete, memory.revisions do the rest. A delete is recoverable from the revision history.
  • The namespace is your API key’s name, not its id — so rotating the key keeps your notes, and a key minted under a different name is a different agent with an empty tree.
  • Writes are always your own tree; there is no field to name someone else. Reads can name another agent via agent, but only with the memory:read:all scope. Two agents that need to share something share it through the activity log, which is public and attributed.
  • Use it for state that has to survive the session: watchlists, the ids you already resolved, what you concluded last week, the preferences your human corrected you on.

Activity — what you report doing

  • activity.create takes a required title, plus kind, channel, detail, a structured payload, an external_ref (a post URL, a campaign id) that makes the claim checkable, and occurred_at when the work happened earlier than now. The reporter is stamped from your credential; you cannot file under another agent’s name.
  • Rows start RECORDED and move RECORDED → PUBLISHED → MEASURED or DISMISSED via activity.update, which also takes the outcome you measured. The ladder is a convention nothing enforces — so mark MEASURED when you actually have an outcome, not to tidy the list.
  • activity.list reads the whole workspace, filterable by agent, kind, and status. Read it before you start: checking what another agent already did is the point of it.
  • This is what makes your work reviewable in the console. Work you did not report is work your human cannot see.

Scopes

Your key carries a subset of ten scopes. A missing one is a 403 naming the scope it needs — read the message and tell your human which box to tick rather than working around it.

ScopeUnlocksDefault
data:readEvery data operation: brand.*, category.*, audience.*, discover.*, enrichment.*, balance.get, usage.summary.Yes
connections:readThe workspace's OWN connected first-party data: data_source.list, search_console.query, analytics.report, linkedin_ads.*, google_ads.*. Free to call, and never granted by default.No
context:readcontext.list and context.get — the standing brief.Yes
context:writecontext.write. Without it you can read the brief but not rewrite it.No
memory:readmemory.list, memory.read, memory.revisions, memory.agents — your own tree.Yes
memory:read:allWidens the memory reads so you may pass another agent's name as "agent". There is no write counterpart.No
memory:writememory.write, memory.edit, memory.mkdir, memory.move, memory.delete — always your own tree.Yes
activity:readactivity.list — what every agent in the workspace reported doing.No
activity:writeactivity.create, and activity.update on your own rows.Yes
activity:write:allWidens activity.update to any agent's rows in the workspace.No
reports:readreport.list, report.runs, report.get and report.document — reading the report documents this workspace's report runs have produced — and report.run, which launches one of the workspace's catalogued reports and spends its credits at the report's price. Never granted by default.No

A key minted without an explicit list gets the five marked default: read the data and the brief, keep your own notes, file your own reports. Rewriting the team’s context and reaching into another agent’s memory or activity are always deliberate grants.

Starter recipes

Endpoint-accurate skeletons. Each assumes you have already read context.list and checked activity.list for prior work.

Daily competitor creative dashboard

Requires: every rival brand activated.

  1. brand.search with q for each competitor; confirm the right row against its description and categories, and keep the id.
  2. brand.competitive_set on your own brand to catch rivals the human did not name.
  3. brand.paid_media.ads.list per rival with { "status": "ACTIVE", "sort": "start_date", "order": "desc" }; page while meta.next_cursor is not null.
  4. memory.read on watchlists/competitor-ads.md, diff the ad id set, then memory.write the new one back.
  5. activity.create with the digest, kind: "digest", and the ad’s landing_url as external_ref.

Weekly category trend brief

Requires: the category activated. Catalog lookup is open.

  1. category.list or category.get to fix the category_id.
  2. category.trends — rank by momentum, not volume, when the question is “what is rising”.
  3. category.news and category.landscape for what moved and who is in the market.
  4. discover.posts with the top trend as q and "since": "7d" for the live conversation behind it (this one costs credits).
  5. memory.write the brief to briefs/<category>-<week>.md; update context.write on marketing_strategy only when a conclusion is durable.
  6. activity.create with kind: "brief".

Share-of-voice report

Requires: every brand in the comparison activated.

  1. brand.search each brand to ids.
  2. brand.compare with brand_ids and a window for the head-to-head snapshot.
  3. brand.mentions.summary per brand for the themes and sentiment behind the numbers.
  4. brand.timeseries with { "metric": "mention_volume", "grain": "week", "window": "1y" } for the trend line.
  5. context.write the conclusion to competitor_analysis; activity.create the report with its link as external_ref.

Audience opportunity tracker

Requires: the audience activated. audience.list is open.

  1. audience.list with q to the audience id.
  2. audience.insights for top_brands, top_themes, and top_content.
  3. audience.influencers, audience.subreddits, audience.podcasts for where the segment actually is.
  4. category.whitespace for the themes nobody is serving.
  5. memory.write the theme list to trackers/audience-<id>.md; on the next run diff against it and report only what changed.

Enrich and qualify a prospect list

No activation needed. Every step here costs credits.

  1. enrichment.company.search with { "platform": "linkedin", "q": "<name>" } to resolve each name to a handle — the identifier the next step takes.
  2. enrichment.company.get with { "platform", "handle" } for the firmographics.
  3. enrichment.company.jobs — open roles are the cheapest expansion signal there is.
  4. enrichment.company.posts for what they say publicly, and discover.ads for whether they are buying (remember: google takes the domain).
  5. memory.write the qualified rows; activity.create with kind: "prospecting" and the count in payload.

Gotchas

  • Read the refusals literally. 402 insufficient_credits or usage_cap_exceeded means stop and tell your human — retrying cannot help. 403 resource_not_activated needs an activation; 403 permission_denied names the scope your key is missing and how it is granted — most scopes you can select yourself when connecting, or mint on an API key. 409 resource_not_live is the one refusal that is not about you: your organization holds that entity and we have not finished collecting its data, so retry later rather than changing anything — details.held_since says when the slot was taken.
  • Respect the rate limit. Throughput is bought per organization and reported in the standard RateLimit-* headers. A 429 carries Retry-After; wait that long rather than backing off blind, and slow down when remaining is low instead of waiting to be refused.
  • Page properly. List operations put the next page on meta.next_cursor — pass it back as cursor with the same filters until it is null. The first page is not the result set.
  • Retry with an Idempotency-Key. Send the header on charging calls and a retry replays the original response unbilled. Without it, a retried timeout can bill twice.
  • Your key is workspace-scoped and revocable. It is a service credential owned by the workspace, not by the person who minted it, and an admin can revoke it at any moment. Treat a sudden 401 as revocation, not as a bug to retry through.
  • Do not hoard raw data. Nothing you paged through is worth re-paging. Write the conclusion to context.write when it is about the business, to memory.write when it is your own working state, and report the work with activity.create. Dumping a thousand rows into memory is not persistence; it is a bill you will pay twice.
  • Quote the request_id. Every response and every error carries one. When something fails, hand it to your human — it is what joins your call to our logs.
Adveron — brand, category, and audience intelligence.
API referenceInstructionsStatusGoogle WorkspacePrivacyTermsData deletionSign in