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.
/agent-createRequired
Requires API key authentication (UGSK_xxx)
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
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"
SDK examples (coming soon)
// 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
{
"id": "..."
}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)
| Method | Path | Purpose |
|---|---|---|
POST | /agent-create | Create a credential; returns the plaintext key once |
GET | /agent-me | List your credentials |
GET | /agent-me/:id | Get one credential's detail |
PATCH | /agent-me/:id | Update limits/scope on a credential |
DELETE | /agent-me/:id | Revoke a credential |
GET | /agent-me/:id/transactions | Paginated transaction log for a credential |
Create request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✓ | Label for the credential (max 120 chars) |
allowedActions | string[] | ✓ | Actions this key may perform (max 10) |
description | string | - | Notes (max 500 chars) |
maxAmountPerTxn | number | - | Per-transaction limit |
maxAmountPerDay | number | - | Rolling daily cap |
currency | string | - | ISO 4217 currency code |
recipientWhitelist | string[] | - | Allowed recipient phones (E.164). Omit = any recipient |
featureKeyScope | string[] | - | Restricts which feature-gated actions apply |
webhookUrl | string | - | HTTPS endpoint notified of credential activity |
channelSource | string | - | Free-text origin tag (e.g. "whatsapp-bot") |
expiresAt | string | - | ISO 8601 expiry timestamp |
Transfer
POST /agent/transfer
Authorization: Bearer agcred_<key>
Content-Type: application/json| Field | Type | Required | Description |
|---|---|---|---|
recipientPhone | string | ✓ | Recipient phone in E.164 format |
amount | number | ✓ | Transfer amount (min 0.01) |
currency | string | ✓ | ISO 4217 currency code |
idempotencyKey | string | ✓ | Stable idempotency key for this request |
note | string | - | Optional transfer note |
callbackUrl | string | - | 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
GET /agent/balance?currency=NGN
Authorization: Bearer agcred_<key>Returns available wallet balance and the credential's remaining daily cap.
Create a payment link
POST /agent/payment-link
Authorization: Bearer agcred_<key>
Content-Type: application/jsonRequires 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.
| Field | Type | Required | Description |
|---|---|---|---|
title | string | ✓ | Shown to the payer (max 200 chars) |
amount | number | ✓ | Amount in major units (0.01–10,000,000) |
currency | string | ✓ | ISO 4217 currency code |
description | string | - | Max 2000 chars |
successRedirectUrl | string | - | Redirect after successful payment |
productType | string | - | Product type enum for the link |
autoReleaseAfterDays | number | - | Auto-release window (3–30 days) |
idempotencyKey | string | - | Min 16 chars, prevents duplicate links on retry |
callbackUrl | string | - | 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
| HTTP | Meaning |
|---|---|
401 | Missing or invalid agcred_ key |
402 | Per-transaction limit exceeded |
403 | Credential frozen, daily cap exhausted, action not in allowedActions, or recipient not whitelisted |
409 | Duplicate idempotencyKey with a different request body |
422 | Validation error - check request body fields |
Related
Common Errors
INVALID_CURRENCYInvalid Currency Code
The currency code provided is not supported.
{
"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.
INSUFFICIENT_BALANCEInsufficient Wallet Balance
The wallet does not have enough balance to complete this transaction.
{
"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.
UNAUTHORIZEDAuthentication Required
The request requires authentication but none was provided.
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or expired authentication token"
}
}Solution: Include a valid API key or JWT token in the Authorization header.
RATE_LIMIT_EXCEEDEDRate Limit Exceeded
Too many requests have been made in a short period.
{
"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?