UGCDocumentation

MCP server

Connect any MCP-compatible LLM to the platform's campaign, slot, wallet, trust, and Relay tools via Streamable HTTP. Discovery, JWT or OAuth auth, and the full tool list.

Updated October 3, 2026
GEThttps://api.ugc.africa/actions-gateway/openapi.json
Required

Connect any MCP-compatible LLM to the platform's campaign, slot, wallet, trust, and Relay tools via Streamable HTTP. Discovery, JWT or OAuth auth, and the full tool list.

Rate Limit

This endpoint is limited to 100 requests per 1 minute per API key.

Rate limit headers are included in all responses: X-RateLimit-Limit, X-RateLimit-Remaining

Interactive API PlaygroundTest this endpoint directly from your browser

Credentials

Your API key is never stored and only used for this request

curl -X GET https://api.ugc.africa/https://api.ugc.africa/actions-gateway/openapi.json \
  -H "Authorization: Bearer YOUR_API_KEY"
Coming soon

SDK examples (coming soon)

JavaScript
// Official Node SDK - coming soon. Use REST (see Getting Started) or fetch() examples.
// Planned: npm install @UGC/node

Official @UGC/* client libraries are on the roadmap. Integrate with the REST API and webhooks today. SDK pages · Email notify

Success

JSON
{
  "id": "..."
}
curl
curl -X GET https://api.ugc.africahttps://api.ugc.africa/actions-gateway/openapi.json \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

The platform exposes a [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server so AI models - Claude, GPT, Gemini, Llama, Mistral, and any other MCP-compatible LLM - can orchestrate campaign, slot, wallet, and Relay workflows through typed, self-describing tool calls.

Not for delegated money movement: MCP is scoped to the authenticated user's own resources. Prefer Agent Credentials (agcred_ keys) when an agent must send transfers or create payment links under hard spend limits.

>

Chat / GPT Actions: for OpenAPI-style host actions (Custom GPT), use the Actions Gateway schema at GET https://api.ugc.africa/actions-gateway/openapi.json (interactive docs: /actions-gateway/docs) with the same automation OAuth IdP.

Discovery

No authentication required for manifest discovery:

http
GET https://api.ugc.africa/.well-known/mcp.json

Returns the public manifest: available tools, schemas, and transport hints. MCP clients fetch this automatically during initialization.


Transport

MechanismURLDescription
Streamable HTTPPOST https://api.ugc.africa/mcpJSON-RPC initialize / tools/list / tools/call
Session GETGET https://api.ugc.africa/mcpOptional session stream (mcp-session-id header)
Session closeDELETE https://api.ugc.africa/mcpEnd Streamable HTTP sessionJSON-RPC tool calls within an established SSE session

Tools

Chat-callable tool names come from the ActionRegistry at runtime (platform, campaign, crypto checkout, and payout packs, including check_username). There are no ugc_* or deed_* aliases. Delegated transfers and Clip Studio are not MCP tools. Supplemental Trust, Relay, Insights, and agent_check_balance are merged without colliding with registry names. Use exact names from GET /.well-known/mcp.json. The published registry name is africa.ugc/ugc. Connector URL: https://api.ugc.africa/mcp (this product's example: https://api.ugc.africa/mcp).

Platform

ToolRequired paramsPurpose
check_usernameusernameCheck whether a username is available. OAuth scope username:read.

Advertiser campaigns

ToolRequired paramsPurpose
campaign_list_mine-List the authenticated advertiser's campaigns. Optional status. Scope campaign:read.
campaign_get_detailcampaignIdGet one campaign the caller owns. Scope campaign:read.
campaign_createtitle, payoutType, advertiserCpmRate, totalBudgetCreate a DRAFT campaign. Fund it separately with campaign_fund. Scope campaign:write.
campaign_fundcampaignIdFund via checkout, wallet, or payment_link. Scope campaign:fund. destructiveHint: confirm before calling.
campaign_featurecampaignIdBuy sponsored placement. Scope campaign:fund. destructiveHint: confirm before calling. If create used purchaseFeaturedPlacement: true, first funding already bundles this - do not call it again for that checkout.
campaign_fund_statuscampaignIdPoll whether funding has settled. Scope campaign:read.
slot_listcampaignIdList creator slots on a campaign the caller owns. Optional status, page, limit. Scope slot:read.

There is no campaign patch, pause, or analytics MCP tool, and no upload tool. Creative files are URLs on assets (and assetVariants when you need more than one kit).

campaign_create body

Channels are targetPlatforms (platform slugs such as whatsapp_status and snapchat). Channels are targetPlatforms only. payoutType is FLAT, CPM_SOCIAL, or CPM_STREAMING. The rate field is advertiserCpmRate (per 1,000 views, or per post when FLAT).

FieldRequiredNotes
titleyesCampaign title
payoutTypeyesFLATCPM_SOCIALCPM_STREAMING
advertiserCpmRateyesPer 1,000 views (CPM types) or per post (FLAT)
totalBudgetyesBudget in USD
descriptionnoBroadcaster brief
campaignTypenoSTANDARD_VIDEO (default), MUSIC_PROMO, MUSIC_PROMO_PRERELEASE, FIXED_FEE, TEXT_DISTRIBUTION, PRODUCT_PLACEMENT, CLIP_CAMPAIGN. CLIP_CAMPAIGN and TEXT_DISTRIBUTION need a feature flag; a disabled flag returns 403 FEATURE_NOT_AVAILABLE.
campaignGoalnoSTANDARD_VIDEO only: AWARENESS, PRODUCT_LAUNCH, APP_INSTALL
campaignModenoBROADCAST (default) or CREATOR_ORIGINAL
clipSourceMode, sourceContentUrl, sourceRightsConfirmednoCLIP_CAMPAIGN. clipSourceMode is RAW_FOOTAGE or PRECLIPPED_TEMPLATE.
languagenoLanguage code, default en
assets, assetVariantsnoCDN URLs plus metadata. Assets may be empty on a DRAFT; required before go-live except TEXT_DISTRIBUTION.
captionTemplate, textContent, requiredHashtags, broadcastInstructionsnotextContent is the verbatim copy for TEXT_DISTRIBUTION.
allowCreatorHook, suppressBrandHashtagnoPersonal intro/outro, and whether to hide the brand-hashtag recommendation
MusicnosoundUrl, soundTitle, soundArtist, musicPromoMode (OFFICIAL_SOUNDUPLOADED_TRACKPRERELEASE_TEASER), soundContentKind, soundReferences, streamingLinks, parentCampaignId, scheduledActivateAt
TargetingnotargetPlatforms, countryAllowlist (empty = all countries), targetNiches, cityTargeting, regionTargeting, customRequirements, minKycTier, minCreatorLevel, minFollowers
flatPayoutTiers, maxSlotsnoTiers are FLAT only. maxSlots is ignored for FLAT (server-computed).
OthernominimumPostDays, minimumPayableViewsPerCycle, minimumPayableViewsTotal, startDate, endDate, conversionUrl, conversionTrackingEnabled, product-placement fields, sourceLinkAccessConfirmed, sourceAssetLink, sourceStorageKey, agencyId, templateId, adDisclosureAccepted, purchaseFeaturedPlacement, idempotencyKey

Creator

ToolRequired paramsPurpose
campaign_discover-Active campaigns with remaining slots. Filters: campaignType, payoutType, platform, country, search, sort (HIGHEST_PAYING, MOST_SLOTS, EXPIRING_SOON, NEW), page, limit. OAuth needs campaign:discover and campaign:read.
slot_reservecampaignIdReserve a slot for the authenticated creator. Scope slot:write.
slot_list_mine-The creator's slots. Optional status. Scope slot:read.
slot_submitslotId, platformSubmit the published post. Also send postUrl (link platforms) or postProofUrls (screenshot platforms such as Snapchat Spotlight). platform is TIKTOK, INSTAGRAM_REELS, YOUTUBE_SHORTS, X_TWITTER, WHATSAPP_STATUS, FACEBOOK_REELS, LINKEDIN, PINTEREST, TELEGRAM_CHANNEL, or SNAPCHAT_SPOTLIGHT. originalAssetUrl is required for CREATOR_ORIGINAL. Scope slot:write.
slot_earningsslotIdPro-rata CPM or flat earnings for one slot. Scope earnings:read.
payout_get_earnings-Creator earnings summary (pending, available, totals). Scope earnings:read.
payout_rate_previewamount, toCurrencyPreview a USD-to-local conversion. Does not move funds. Scope earnings:read.
payout_transfer_to_wallet-Move cleared earnings into the USD wallet. Optional amount (omit = full available balance). Scope payout:transfer. destructiveHint: confirm the amount first.
payout_transfer_earnings-Move cleared earnings to USD_WALLET, LOCAL_WALLET (needs preferredCurrency), or CRYPTO. Scope payout:transfer. destructiveHint: confirm amount and destination first.

Wallet

ToolRequired paramsPurpose
wallet_get_balance-Balances per currency, minus locked amounts. Optional currency. Scope wallet:read.
wallet_get_history-Paginated history. Optional days, currency, limit. Scope wallet:read.
wallet_generate_crypto_addresscurrency, networkStatic crypto deposit address for the caller. Scope crypto:deposit.

Trust

ToolRequired paramsPurpose
trust_get_summaryuserIdTrustScore and verification status for a user

Relay (automated wallet rules)

ToolRequired paramsPurpose
relay_list_rules-List active Relay rules. Optional includeInactive.
relay_create_rulename, actionType, scheduleType, fromCurrency, amountTypeCreate a draft rule. The user must approve it in the app before it can execute.
relay_pause_ruleruleIdPause an active rule
Relay rules can move real funds. Agents must direct users to the approval flow. Never expose your UGSK_ API Key, or MCP tokens, to LLM context windows.

Insights

ToolRequired paramsPurpose
spending_get_insights-Spending summaries, anomaly alerts, cash-flow predictions. Optional type, unreadOnly, limit. Requires the relay insights feature flag.

Crypto checkout

ToolRequired paramsPurpose
advertiser_checkout_create_cryptocurrency, networkPay a campaign-funding or advertiser-checkout payment link with cryptocurrency. Pass paymentLinkId (or deprecated paymentId). Scope campaign:fund. destructiveHint: confirm before calling.

Agent credential (read only)

ToolRequired paramsPurpose
agent_check_balance-Available wallet balance and remaining Agent Credential daily cap. Optional currency. Delegated transfers stay on the Agent Credential HTTP API (POST /agent/transfer); they are not an MCP tool.

Idempotency

Pass Idempotency-Key: <unique_value> on mutating tool calls (campaign_create, campaign_fund, slot_reserve, slot_submit, payout transfers, and others). Several of those tools also accept idempotencyKey in the body when the header is absent. Do not retry a money tool without the same key, and do not call it until the user has confirmed.


Error codes

Tool calls surface the same structured errors as the underlying REST APIs. Agents can make deterministic decisions on every failure:

HTTPApiErrorCode exampleMeaning
401AUTH_REQUIREDMissing or invalid JWT / OAuth token
403MCP_NOT_ENABLEDAccount lacks mcp_server entitlement
403INSUFFICIENT_SCOPEOAuth token missing a required action scope (e.g. campaign:fund)
403WALLET_FROZENAccount is frozen
409SLOT_NO_CAPACITYNo remaining slot capacity on the campaign
422WALLET_INSUFFICIENT_FUNDSNot enough balance
429RATE_LIMITEDToo many requests

LLM compatibility

Model familyMCP support
Claude (Anthropic)✓ Native MCP client
GPT (OpenAI)✓ Via MCP adapter
Gemini (Google)✓ Via MCP adapter
Llama / Mistral (open source)✓ Via MCP adapter
Any MCP-compatible agent✓

  • AI agents overview
  • Agent Credentials - scoped agcred_ keys for delegated transfers
  • Automation - webhook and OAuth integrations
  • Actions Gateway OpenAPI: https://api.ugc.africa/actions-gateway/openapi.json · docs /actions-gateway/docs

Common Errors

400INVALID_CURRENCY

Invalid Currency Code

The currency code provided is not supported.

Example Response
JSON
{
  "success": false,
  "error": {
    "code": "INVALID_CURRENCY",
    "message": "Currency code \"XYZ\" is not supported",
    "supportedCurrencies": [
      "USD",
      "EUR",
      "GBP",
      "GHS",
      "NGN"
    ]
  }
}

Solution: Use a valid ISO 4217 currency code. See our list of supported currencies.

400INSUFFICIENT_BALANCE

Insufficient Wallet Balance

The wallet does not have enough balance to complete this transaction.

Example Response
JSON
{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Insufficient balance in USD wallet",
    "required": 5000,
    "available": 2500
  }
}

Solution: Add funds to your wallet or use a different payment method.

401UNAUTHORIZED

Authentication Required

The request requires authentication but none was provided.

Example Response
JSON
{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or expired authentication token"
  }
}

Solution: Include a valid API key or JWT token in the Authorization header.

429RATE_LIMIT_EXCEEDED

Rate Limit Exceeded

Too many requests have been made in a short period.

Example Response
JSON
{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Try again in 60 seconds",
    "retryAfter": 60
  }
}

Solution: Wait for the specified retry period before making another request. Consider implementing exponential backoff.

Did this solve your problem?