UGCDocumentation

Agent Credentials reference

Issue scoped agcred_ keys so AI agents can send wallet transfers and create payment links on your behalf - with per-transaction limits, daily caps, and idempotent retries.

Updated October 3, 2026
POST/agent-create
Required

Issue scoped agcred_ keys so AI agents can send wallet transfers and create payment links on your behalf - with per-transaction limits, daily caps, and idempotent retries.

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 POST https://api.ugc.africa/agent-create \
  -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 POST https://api.ugc.africa/agent-create \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Agent Credentials let you issue scoped keys (agcred_...) to AI agents and automation scripts. An agent holding an agcred_ key can send wallet transfers and create payment links on your behalf—nothing more, nothing less.


How it works

1. Create a credential: POST /agent-create (authenticated as the account owner, JWT), specifying allowedActions, and optionally maxAmountPerTxn, maxAmountPerDay, currency, recipientWhitelist, and webhookUrl. The plaintext key is returned once.

2. Your agent holds the key server-side and calls the endpoints below with Authorization: Bearer agcred_<key>.

3. The platform validates the key, checks it's allowed to perform the requested action, enforces spend limits atomically, and executes the transfer or payment-link creation.

4. If webhookUrl (or a per-call callbackUrl) is set, the platform notifies it of the outcome. Verify the callback with the X-UGC-Signature: v1=<hex> header (HMAC-SHA256 over {timestamp}.{rawBody} using your credential's signing secret) and the accompanying X-UGC-Timestamp header.


Managing credentials (owner, JWT auth)

MethodPathPurpose
POST/agent-createCreate a credential; returns the plaintext key once
GET/agent-meList your credentials
GET/agent-me/:idGet one credential's detail
PATCH/agent-me/:idUpdate limits/scope on a credential
DELETE/agent-me/:idRevoke a credential
GET/agent-me/:id/transactionsPaginated transaction log for a credential

Create request body

FieldTypeRequiredDescription
namestring✓Label for the credential (max 120 chars)
allowedActionsstring[]✓Actions this key may perform (max 10)
descriptionstring-Notes (max 500 chars)
maxAmountPerTxnnumber-Per-transaction limit
maxAmountPerDaynumber-Rolling daily cap
currencystring-ISO 4217 currency code
recipientWhiteliststring[]-Allowed recipient phones (E.164). Omit = any recipient
featureKeyScopestring[]-Restricts which feature-gated actions apply
webhookUrlstring-HTTPS endpoint notified of credential activity
channelSourcestring-Free-text origin tag (e.g. "whatsapp-bot")
expiresAtstring-ISO 8601 expiry timestamp

Transfer

http
POST /agent/transfer
Authorization: Bearer agcred_<key>
Content-Type: application/json
FieldTypeRequiredDescription
recipientPhonestring✓Recipient phone in E.164 format
amountnumber✓Transfer amount (min 0.01)
currencystring✓ISO 4217 currency code
idempotencyKeystring✓Stable idempotency key for this request
notestring-Optional transfer note
callbackUrlstring-Overrides the credential's webhookUrl for this call

If the amount or recipient falls outside the credential's scope and fallback is enabled, the response returns a draft-intent URL for first-party user confirmation instead of settling from the agent call alone.


Check balance

http
GET /agent/balance?currency=NGN
Authorization: Bearer agcred_<key>

Returns available wallet balance and the credential's remaining daily cap.


http
POST /agent/payment-link
Authorization: Bearer agcred_<key>
Content-Type: application/json

Requires PAYMENT_LINK_CREATE in the credential's allowedActions. Creates a payment link on behalf of the account holder (campaign funding or invoicing) and returns a public checkout URL.

FieldTypeRequiredDescription
titlestring✓Shown to the payer (max 200 chars)
amountnumber✓Amount in major units (0.01–10,000,000)
currencystring✓ISO 4217 currency code
descriptionstring-Max 2000 chars
successRedirectUrlstring-Redirect after successful payment
productTypestring-Product type enum for the link
autoReleaseAfterDaysnumber-Auto-release window (3–30 days)
idempotencyKeystring-Min 16 chars, prevents duplicate links on retry
callbackUrlstring-Notified on payment_link.created

Idempotency

Pass idempotencyKey on transfer and payment-link creation calls. If the platform has already processed a request with the same key for this credential, it returns the original response instead of creating a duplicate—making agent retries safe.


Errors

HTTPMeaning
401Missing or invalid agcred_ key
402Per-transaction limit exceeded
403Credential frozen, daily cap exhausted, action not in allowedActions, or recipient not whitelisted
409Duplicate idempotencyKey with a different request body
422Validation error - check request body fields

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?