Developer docs
On this page
Before you start#
- An API key with the scopes
readandpayments:write. See Create a key. - curl, or Node.js 18 or later (fetch is built in), or Python 3 with
requests.
There is no test mode: these calls use your live data. Reading is always safe. Step 4 records money against a subscriber, so pick one you set up for testing.
Set up#
Put the key in an environment variable, then add a small helper. The JavaScript and Python examples below use it.
# Keep the key out of your code: put it in the environment.
export CORESYNC_API_KEY="cs_live_xxx"1. Check your key#
GET /account says which key you are and which ISP it acts on, with the ISP's currency and time zone. Call it first.
curl https://coresyncapi.avitechcloud.com/api/v1/account \
-H "X-API-Key: $CORESYNC_API_KEY"{
"key": {
"name": "amani-crm",
"prefix": "cs_live_xxxx",
"kind": "TENANT",
"scopes": [
"read",
"write"
],
"rate_limit_per_minute": 120,
"expires_at": null
},
"tenant": {
"code": "AMANI",
"name": "Amani Link",
"status": "ACTIVE",
"currency": "KES",
"country_code": "KE",
"timezone": "Africa/Nairobi"
}
}A 401 means the key is missing, wrong, revoked or expired. The code in the answer says which.
2. List subscribers#
GET /subscribers returns one page of subscribers, newest first. Filter by status, or search with q.
curl "https://coresyncapi.avitechcloud.com/api/v1/subscribers?status=ACTIVE&size=20" \
-H "X-API-Key: $CORESYNC_API_KEY"{
"items": [
{
"id": "3f2a6c1e-8b7d-4c1a-9e2f-1a2b3c4d5e6f",
"account_number": "AL-01042",
"subscriber_code": "AL1042",
"username": "wanjiku.k",
"name": "Wanjiku Kamau",
"phone": "+254712345678",
"email": "wanjiku@example.com",
"status": "ACTIVE",
"service_type": "PPPOE",
"online": true,
"plan_name": "Home 10 Mbps",
"expires_at": "2026-11-25T09:00:00Z",
"credit_balance": {
"amount": "300.00",
"currency": "KES"
}
}
],
"total": 137,
"page": 1,
"size": 50
}total counts every match, across all pages. To read them all, see Pagination.
3. Find a subscriber by phone#
GET /subscribers/lookup finds subscribers by exactly one of phone, email or account. A phone matches in any format: 0712345678, 254712345678 or +254 712 345 678.
curl -G https://coresyncapi.avitechcloud.com/api/v1/subscribers/lookup \
--data-urlencode "phone=+254712345678" \
-H "X-API-Key: $CORESYNC_API_KEY"Encode the + in a query string as %2B. The examples do it for you (--data-urlencode, URLSearchParams, params=).
The answer is a list, because one phone can belong to several accounts. Keep the subscriber's id: every /subscribers/{id} call takes it.
4. Record a payment#
POST /payments records money you received outside CoreSync's own channels: cash, a bank transfer or an M-Pesa receipt you hold. It needs the scope payments:write.
It is applied the same way an M-Pesa payment is. It goes to the subscriber's wallet, renews their subscription when it covers the plan price, reactivates them if they were suspended, and sends payment.received to your webhooks.
curl https://coresyncapi.avitechcloud.com/api/v1/payments \
-H "X-API-Key: $CORESYNC_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 4d1c9f0e-7a2b-4f43-9a51-2f0c7c1d8e11" \
-d '{
"subscriber_id": "3f2a6c1e-8b7d-4c1a-9e2f-1a2b3c4d5e6f",
"amount": "1500.00",
"provider": "MPESA",
"reference": "SAMPLE7Q2Z"
}'{
"id": "1c2d3e4f-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
"subscriber": {
"id": "3f2a6c1e-8b7d-4c1a-9e2f-1a2b3c4d5e6f",
"account_number": "AL-01042",
"name": "Wanjiku Kamau",
"phone": "+254712345678"
},
"amount": {
"amount": "1500.00",
"currency": "KES"
},
"provider": "MPESA",
"method": "PAYBILL",
"reference": "SAMPLE7Q2Z",
"payer_phone": "+254712345678",
"account_reference": "AL1042",
"status": "COMPLETED",
"applied": true,
"applied_at": "2026-10-25T09:00:05Z",
"not_applied_amount": {
"amount": "0.00",
"currency": "KES"
},
"received_at": "2026-10-25T09:00:00Z"
}- Idempotency-Key is required. Make one per payment and reuse it if you retry. A retry within 24 hours returns the first answer instead of paying twice. Idempotency
- reference is the receipt. A provider and reference pair is only ever recorded once, so passing the real M-Pesa code makes a duplicate impossible.
201means recorded and applied.200means this receipt was already recorded for this subscriber, and nothing changed.
Next steps#
Stuck, or missing something? Tell us what you're building.
hello@coresyncisp.com