Business Account API: provisioning, OAuth, and the resource map
This is the proposed v1 Business Account API (status: proposed, flagged for engineering confirmation; Live API today and the Business Account API roadmap maps it to the live /api/thirdparty endpoints). Everything the five Get Started steps and every product do in Brand Control Center would be available as an API, so a Business Account could be created, configured, launched, and operated programmatically, by the owner's own stack, by a partner or aggregator acting for many accounts, or by an AI agent. Base URL https://api.begenuin.com/v1; JSON in and out; every write returns the resulting resource and, where a confirmation is normally required, a proposal you approve with one call.
Getting access to a Business Account
| Who | How | Scope |
|---|---|---|
| The account owner or a teammate | API key from Settings → Developers (sandbox at sign-up, live at launch), scoped to the account and the key holder's role (see Invite your team and assign roles) | One Business Account |
| A partner, aggregator, or platform acting for many accounts | OAuth 2.0 client credentials: POST /oauth/token with client_id, client_secret, scope, and the account_id to act on; tokens expire in 1 hour | Every account that granted the client access (see Partner and reseller program) |
| A new customer provisioned by a partner | POST /accounts creates the Business Account, the first brand, and a sandbox key, and returns the owner's verification link; POST /accounts/{accountId}/brands:import adds brands in bulk | The created account |
| An AI buyer agent | AdCP endpoints with a buyer key (see AdCP: make your inventory discoverable to AI buyer agents) | Marketplace only |
Scopes: account:read, account:write, brand:read, brand:write, content:write, network:write, members:write, partners:write, monetize:write, reports:read, octo:act. A key or token never exceeds the role it was issued for; octo:act lets an integration raise proposals but not approve them unless it also holds the matching write scope.
curl -X POST https://api.begenuin.com/v1/oauth/token \
-d client_id=$CLIENT_ID -d client_secret=$CLIENT_SECRET \
-d account_id=acc_123 -d scope="brand:write network:write reports:read"
curl -X POST https://api.begenuin.com/v1/accounts \
-H "Authorization: Bearer $PARTNER_TOKEN" \
-d '{"company":"Northwind Health","brand":"Northwind Wellness","companyType":"consumer-services","ownerEmail":"owner@northwindhealth.example"}'Resource map by product
Business Account & access (see Business Account API: provisioning, OAuth, and the resource map)
| Call | Purpose |
|---|---|
| POST /oauth/token | Exchange client credentials for an access token scoped to a Business Account |
| POST /accounts | Create a Business Account (company, first brand, company type, owner email); returns the verification link and a sandbox key |
| GET /accounts/{accountId} | Read the Business Account: plan, brands, roles, verification state |
| PATCH /accounts/{accountId} | Update company name, type, billing contact, legal entity |
| GET /accounts/{accountId}/keys | List sandbox and live API keys and their scopes |
| POST /accounts/{accountId}/keys | Issue a key with a role scope (sandbox or live) |
| POST /keys/{keyId}:rotate | Rotate a key; the old key keeps working for 24 hours |
| GET /accounts/{accountId}/team | List teammates, roles, and brand scopes |
| POST /accounts/{accountId}/team/invitations | Invite a teammate with a role and the brands it is scoped to |
| PATCH /team/{memberId} | Change a role, re-scope brands, require two-factor, or remove |
| GET /accounts/{accountId}/audit | Audit log of every change by user and time |
Brands, kit, properties & context (see Business Account API: provisioning, OAuth, and the resource map)
| Call | Purpose |
|---|---|
| GET /accounts/{accountId}/brands | List brands in the Business Account |
| POST /accounts/{accountId}/brands | Create a brand (publisher property, client, product line) under the account |
| POST /accounts/{accountId}/brands:import | Bulk-create brands from a CSV or a list (aggregators: one per property or client) |
| GET /brands/{brandId}/kit | Read the brand kit: logos, colors, typeface, voice, description |
| POST /brands/{brandId}/kit:sample | Sample the kit from a URL (homepage, app listing) and return it rendered for review |
| PUT /brands/{brandId}/kit | Approve or edit the kit; applies to every player, email, and listing |
| GET /brands/{brandId}/properties | Domains, subdomains, and apps that belong to the brand, with verification state |
| POST /brands/{brandId}/properties | Add a domain or app; returns the DNS TXT and meta-tag verification lines |
| POST /properties/{propertyId}:verify | Trigger verification (DNS, meta tag, or first SDK call) |
| GET /brands/{brandId}/sources | Content sources: RSS, YouTube, TikTok, Instagram, Drive, catalog feed, with read schedule |
| POST /brands/{brandId}/sources | Connect a content source with a read schedule |
| GET /brands/{brandId}/context | Brand context: crawl status, guidelines, audience notes, catalog, partner rules, policies, technical notes, legal |
| PUT /brands/{brandId}/context | Add or replace a context section (guidelines, audience, policies, technical notes, legal paper) |
| POST /brands/{brandId}/context:crawl | Start or re-run the website crawler across verified properties |
Network & grid (see Network: what it does and where to start)
| Call | Purpose |
|---|---|
| GET /brands/{brandId}/network | Network model (Owned, Extended, Commerce, Retail), listing state, and what it switches on |
| PUT /brands/{brandId}/network | Choose or change the network model |
| GET /brands/{brandId}/page-types | Page types on the Hierarchical Grid per property |
| GET /brands/{brandId}/placements | Placements with size, allowed experiences, context, and placementId |
| POST /brands/{brandId}/placements | Register a placement on a page type |
| POST /brands/{brandId}/placements:import | Import the grid from an ad server's ad units or an inventory map |
| POST /brands/{brandId}/placements:publish | Approve and publish the grid; issues placementIds |
Onsite placements & players (see Onsite: what it does and where to start)
| Call | Purpose |
|---|---|
| PUT /placements/{placementId}/experiences | Allowed player experiences per placement (Shorts, Shoppable, Community, Live) |
| GET /placements/{placementId}/embed | Embed snippet for the placement (Web SDK attributes pre-filled) |
| PUT /placements/{placementId}/settings | Player controls, feed settings, sticky mini-player, keywords, mode |
| GET /placements/{placementId}/feed | Server-side render of the ranked feed for a page context (SSR and native apps) |
| POST /placements/{placementId}/experiments | Create an experiment or holdout on a placement |
Content, communities & Studio (see Studio: what it does and where to start)
| Call | Purpose |
|---|---|
| GET /brands/{brandId}/communities | Communities with their groups, tags, visibility, and member counts |
| POST /brands/{brandId}/communities | Create a community (or accept the proposed one) with groups and tags |
| PATCH /communities/{communityId} | Rename, merge, change visibility, guidelines, or tags |
| POST /communities/{communityId}/groups | Add a group with its keywords, topics, and categories |
| POST /brands/{brandId}/videos:import | Import videos from a source, URL list, or upload session |
| GET /brands/{brandId}/videos | Videos with community, group, tags, and classification confidence |
| POST /videos/{videoId}:classify | Re-run classification or set community, group, keywords, topics, categories |
| POST /videos/{videoId}/clips | Studio: generate clips from long-form, with captions, titles, and covers |
| POST /brands/{brandId}/studio/jobs | Studio job: catalog product videos, text-to-video explainers, adaptation per platform, live-to-clips |
| GET /brands/{brandId}/hub | The content hub: address, sections, launch checklist state |
| POST /brands/{brandId}/hub:launch | Launch the hub on a Genuin address or a verified domain; issues the live key |
| POST /communities/{communityId}/posts | Post a video or a creator post into a group |
| PUT /brands/{brandId}/syndication | Platform permissions and the posting cadence per platform |
| POST /posts/{postId}:schedule | Schedule, hold, or edit a syndicated post |
Feeds & distribution (see Network: what it does and where to start)
| Call | Purpose |
|---|---|
| GET /brands/{brandId}/feeds | Distribution feeds with dimension, value, where they may run, and what wraps them |
| POST /brands/{brandId}/feeds | Create a feed by keyword, category, brand, or page context |
| POST /feeds/{feedId}:distribute | Approve where a feed may run and what wraps it; starts distribution |
| GET /feeds/{feedId}/reach | Expected and actual reach across the 7,000+ apps and sites |
| GET /network/directory | The network directory: brands, properties, and placements open to partners |
| PUT /brands/{brandId}/network/listing | How your network appears in the directory |
| POST /brands/{brandId}/acceptances | Accept partner content into your placements under your rules |
| POST /brands/{brandId}/destinations | Create an Extended O&O or Generative Destination on a Genuin domain |
Members, creators & subscriptions (see Controls: what it does and where to start)
| Call | Purpose |
|---|---|
| POST /sessions | Auto login token exchange: your signed user token for a Genuin session |
| PUT /brands/{brandId}/auth | Auto login provider, claims passed, consent behaviour, member-only communities |
| GET /brands/{brandId}/creators | Creators, hosts, and contributors with tier and groups |
| POST /brands/{brandId}/creators:invite | Invite creators with a tier and the groups they may post into |
| POST /brands/{brandId}/quests | Create a Quest: brief, deadline, reward, target group |
| GET /brands/{brandId}/tiers | Member tiers (Free and paid) with price, interval, trial, and unlocks |
| POST /brands/{brandId}/tiers | Create or edit a tier: name, price, interval, trial, promo, unlocks, cap |
| POST /brands/{brandId}/tiers:publish | Approve and publish tiers; paid tiers go live when payouts are verified |
| GET /brands/{brandId}/members | Member roster with tier, status, renewal date, and source |
| POST /brands/{brandId}/members:import | Import members from CSV, CRM, loyalty, or subscriber file onto a tier |
| PATCH /members/{memberId} | Move a member between tiers, comp, pause, or cancel |
| GET /brands/{brandId}/subscriptions | Active, trialing, past-due, and cancelled subscriptions |
Moderation, guidelines & brand safety (see Controls: what it does and where to start)
| Call | Purpose |
|---|---|
| GET /brands/{brandId}/moderation | Moderation baseline, reviewer roles, SLA |
| PUT /brands/{brandId}/moderation | Set the baseline (Standard or Strict) and the queue owners |
| GET /brands/{brandId}/moderation/queue | Items waiting for a human decision |
| POST /moderation/{itemId}:decide | Approve, remove, or escalate a queued item; appeals use the same call |
| PUT /brands/{brandId}/guidelines | Community guidelines and appeal policy |
| PUT /brands/{brandId}/brand-safety | GARM-aligned brand safety profile and competitive exclusions |
| PUT /brands/{brandId}/blocklists | Keyword, topic, advertiser, and domain blocklists |
| GET /accounts/{accountId}/roles | Account roles, community roles, and creator tiers with their permissions |
| PUT /accounts/{accountId}/security | Two-factor requirement and SSO for BCC |
Partners & demand (see Monetize: what it does and where to start)
| Call | Purpose |
|---|---|
| GET /brands/{brandId}/partners | Brand, demand, publisher, and data partners with classification and edge |
| POST /brands/{brandId}/partners:invite | Invite a partner with direction, permissions, groups, and split or price |
| POST /partner-requests/{requestId}:decide | Accept or decline an incoming partner request |
| PUT /partners/{partnerId}/edge | Change a partner's permissions, groups, or economics |
| POST /brands/{brandId}/sponsorships | Paid Partner Post or Takeover: offer, budget, CPM, dates, placements |
| GET /brands/{brandId}/demand-sources | Demand sources (Genuin network, partners, programmatic, commerce, subscriptions) and their state |
| POST /demand-sources/{sourceId}:activate | Switch a demand source on (or off) in order |
| PUT /brands/{brandId}/ad-server | Genuin Ad Server or partner ad server connection, floors, and yield rules |
Plans, agreements, payouts & revenue (see Monetize: what it does and where to start)
| Call | Purpose |
|---|---|
| GET /plans | Plans, pricing tiers, add-ons, and revenue-share schedule |
| PUT /accounts/{accountId}/plan | Choose or change the plan |
| GET /accounts/{accountId}/wallet | Credits, cash balance, usage, and invoices |
| POST /accounts/{accountId}/agreements | Draft the agreement for the model (revenue share, platform, managed, commerce, buyer) |
| POST /agreements/{agreementId}:send | Route the agreement to the signer; status moves to awaiting signature |
| GET /agreements/{agreementId} | Agreement status, terms, and the executed copy |
| GET /brands/{brandId}/seller-files | ads.txt, app-ads.txt, and sellers.json lines per domain and app, with verification state |
| POST /brands/{brandId}/seller-files:verify | Re-crawl and validate seller files |
| PUT /accounts/{accountId}/payouts | Payout details and calendar (entered by the owner; verified before paid tiers and demand go live) |
| POST /brands/{brandId}/linkouts | Dynamic in-video linkouts and affiliate programs attached to videos or groups |
| GET /creators/{creatorId}/wallet | Creator Wallet: earnings, share, payout status |
| GET /accounts/{accountId}/invoices | Invoices and usage statements |
Marketplace, packages & AdCP (see Marketplace: what it does and where to start)
| Call | Purpose |
|---|---|
| POST /brands/{brandId}/packages | Build a package from placements, feeds, and capabilities with a forecast |
| POST /packages/{packageId}/listings | List a package on the Marketplace (and AdCP) |
| GET /packages/{packageId}/forecast | Outcome forecast block: reach, eCPM lift, revenue range |
| GET /marketplace/listings | Buyer side: search listings by vertical, persona, journey, placement style |
| POST /media-buys | Buyer side: buy a package or a Paid Partner Post |
| GET /adcp/products | AdCP get_products for AI buyer agents |
| POST /adcp/media-buys | AdCP create_media_buy |
Offsite tags, identity & attribution (see Offsite: what it does and where to start)
| Call | Purpose |
|---|---|
| POST /brands/{brandId}/tags | Generate an offsite tag: VAST, JavaScript display, dynamic feed, audience extension |
| GET /tags/{tagId} | Tag URL, macros, consent passthrough, and creative preview |
| POST /conversions | Server-side conversion API for attribution postbacks |
| PUT /brands/{brandId}/identity | ID graph settings: hashed identifiers, consent, channels |
| POST /brands/{brandId}/creatives | Turn community content into ad creative for a media plan |
Octo, proposals & autonomy (see Octo: what it does and where to start)
| Call | Purpose |
|---|---|
| POST /octo/ask | Ask a question about the account in plain language; answers with the article and the setting |
| POST /octo/act | Ask for a change; returns a proposal to approve |
| GET /brands/{brandId}/proposals | Pending proposals with what they change and why |
| POST /proposals/{proposalId}:approve | Approve, edit, or decline a proposal (the confirmation step in every article) |
| PUT /brands/{brandId}/autonomy | Per change kind: ask every time, do and report, or off |
| POST /octo/resolve | Generative commerce routing: resolve intent at serve time to a catalog, partner, or assistant surface |
| POST /support/threads | Open a support thread; Octo answers first and brings in a person when needed |
Reports & intelligence (see Octo: what it does and where to start)
| Call | Purpose |
|---|---|
| GET /reports/engagement | Watch time, completion, lift, cohorts by placement, feed, community |
| GET /reports/revenue | Revenue by placement, partner, source, tier; payouts and creator shares |
| GET /reports/attribution | Closed-loop commerce, conversion forecasts, offsite attribution |
| GET /reports/margin | Revenue per impression and net margin on ad spend |
| GET /reports/distribution | Syndication and network distribution by platform, partner, feed |
| GET /reports/relevance | Relevance OS dashboard data |
| GET /brands/{brandId}/segments | Audience segments from onsite, offsite, and offline signals |
| POST /brands/{brandId}/segments | Define a segment from signals and cohorts |
| POST /intelligence/signals | Intelligence SDK: send your own signals into the graph under consent |
Webhooks, SDK sessions & billing (see Webhooks and events)
| Call | Purpose |
|---|---|
| POST /accounts/{accountId}/webhooks | Subscribe to events (proposal.created, placement.published, member.subscribed, revenue.posted, moderation.flagged, …) |
| GET /events | Event catalog and delivery log with retries |
| GET /status | Platform status and incident feed |
| GET /changelog | API and SDK versions and deprecations |
| GET /glossary | Glossary terms as JSON (also served as llms.txt) |
| PUT /accounts/{accountId}/privacy | Data residency, retention, consent defaults, DSAR endpoint |
| GET /sdk/config | Runtime configuration the Web and mobile SDKs fetch on init (placements, experiences, kit) |
Conventions
- Ids are prefixed (
acc_,brd_,plc_,cmt_,vid_,fd_,mbr_,prt_,agr_,prp_); list calls page withcursorandlimit; filters are query parameters. - Writes that BCC would ask you to confirm return
202with aproposalobject;POST /proposals/{proposalId}:approveapplies it,:declinediscards it, and a brand's autonomy setting (see Octo Autonomy and Approvals) can auto-approve a kind of change. - Every change emits a webhook event (see Webhooks and events):
proposal.created,placement.published,hub.launched,member.subscribed,partner.accepted,agreement.signed,revenue.posted,moderation.flagged. - Rate limits: 600 requests per minute per key or token, report queries 60 per minute;
X-RateLimit-Remainingon every response. Errors are JSON withcode,message,docs_url. - SDKs: the proposed
@genuin/sdk(Node) andgenuin(Python) server SDKs would wrap every call above with the same names used in the API & SDK block of each article; on the client, the live Web SDK 2.0.6 (see Embed the Genuin Web SDK on your website), iOS and Android SDKs 2.1.5 (see Integrate the Genuin iOS SDK and Integrate the Genuin Android SDK), React Native 3.0.3 (see Integrate the Genuin SDK with React Native apps), and Flutter (see Integrate the Genuin SDK with Flutter apps) already render the player and sign members in.
API & SDK
Access: the calls in the table are the proposed Business Account API (see Business Account API: provisioning, OAuth, and the resource map), authenticated with a key scoped to the account and a role or an OAuth client acting for it; every confirmation in this article becomes a proposal you can approve by API (POST /proposals/{proposalId}:approve). Live today, the server API under /api/thirdparty authenticates with a gn-access-token (see Generate an access token), and Live API today and the Business Account API roadmap maps what is live to what is proposed.
| Call | Purpose |
|---|---|
| POST /oauth/token | Exchange client credentials for an access token scoped to a Business Account |
| POST /accounts | Create a Business Account (company, first brand, company type, owner email); returns the verification link and a sandbox key |
| GET /accounts/{accountId} | Read the Business Account: plan, brands, roles, verification state |
| POST /accounts/{accountId}/brands:import | Bulk-create brands from a CSV or a list (aggregators: one per property or client) |
| POST /accounts/{accountId}/keys | Issue a key with a role scope (sandbox or live) |
| POST /accounts/{accountId}/team/invitations | Invite a teammate with a role and the brands it is scoped to |
| POST /accounts/{accountId}/webhooks | Subscribe to events (proposal.created, placement.published, member.subscribed, revenue.posted, moderation.flagged, …) |
// proposed server SDK (Business Account API)
import { Genuin } from '@genuin/sdk';
const genuin = new Genuin({ apiKey: process.env.GENUIN_KEY });
await genuin.auth.token({ clientId, clientSecret, accountId, scope });
await genuin.accounts.create({ company, brand, companyType, ownerEmail });
await genuin.accounts.get(accountId);Live today: Generate an access token · Environments, credentials, and test data · Embed the Genuin Web SDK on your website · Integrate the Genuin iOS SDK.
SDKs: Web SDK 2.0.6 (see Embed the Genuin Web SDK on your website), iOS SDK 2.1.5 (see Integrate the Genuin iOS SDK), Android SDK 2.1.5 (see Integrate the Genuin Android SDK), React Native 3.0.3 (see Integrate the Genuin SDK with React Native apps), and Flutter (see Integrate the Genuin SDK with Flutter apps) render Genuin and sign members in; the Node (@genuin/sdk) and Python (genuin) server SDKs are proposed with Business Account API: provisioning, OAuth, and the resource map.

