Kolect.

Developers

Pulling settled payments into your ERP

A read-only JSON API. It lists payments that have settled, one school at a time, for that school's own finance systems to post to their ledger. It cannot create, verify or change a payment.

Base URL

Every path below is relative to the school's own address, never the platform's. Open this page on a school's address to see it filled in.

https://{school}.kolect.test/api/v1

Authentication

Send the school's token as a bearer token on every request. A token belongs to one school and works only on that school's address. There is no session and no cookie.

curl "https://{school}.kolect.test/api/v1/payments?from=2026-09-01" \
  -H "Authorization: Bearer kol_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Accept: application/json"

Treat the token as a password: it is shown once when issued, stored only as a hash, and a leaked one is revoked and replaced rather than rotated in place.

Listing payments

GET https://{school}.kolect.test/api/v1/payments

Returns settled payments, oldest first by the moment they were paid. Payments still pending, in flight, failed or refunded are never included, so everything you receive can go straight to the ledger. Every filter is optional and they combine.

from
A calendar day, YYYY-MM-DD, in the institution's time zone. Payments paid at or after the start of that day.
to
A calendar day, inclusive, in the same time zone. Must not be before `from`.
paid_since
A date-time, ISO 8601 with offset. Payments paid at or after that instant. Inclusive on purpose, see polling below.
collector
A collector code, such as CSC. Case does not matter.
session
An academic session by name, such as 2025/2026.
matric
One student's matric number, in any spelling the school uses.
per_page
Rows per page. Default and ceiling are given below.
cursor
Opaque. Take it from links.next; never build one.

Example response

{
    "data": [
        {
            "reference": "UCP-2526-CSC-01J8ZK3Q9V",
            "gateway_reference": "CR-7f3a9c1e",
            "status": "successful",
            "currency": "NGN",
            "amount_minor": 1250000,
            "amount": "12500.00",
            "service_charge_minor": 100000,
            "service_charge": "1000.00",
            "total_charged_minor": 1350000,
            "total_charged": "13500.00",
            "channel": "whatsapp",
            "payment_method": "card",
            "payment_provider": "credo",
            "paid_at": "2026-09-15T09:03:11+00:00",
            "verified_at": "2026-09-15T09:03:14+00:00",
            "settled_at": "2026-09-16T02:00:00+00:00",
            "settled_amount_minor": 1250000,
            "student": {
                "matric_number": "CSC/2024/017",
                "first_name": "Adaobi",
                "last_name": "Okafor",
                "other_names": null,
                "email": "adaobi.okafor@example.edu.ng"
            },
            "collector": {
                "code": "CSC",
                "name": "Computer Science",
                "type": "department"
            },
            "collection": {
                "code": "DUES",
                "name": "Departmental Dues",
                "term": "full_session",
                "level": 200
            },
            "academic_session": {
                "name": "2025/2026",
                "short_code": "2526"
            },
            "receipt": {
                "number": "RCP-2526-CSC-000418",
                "verification_code": "K7Q2-M9XA",
                "verify_url": "https://kolect.online/verify/K7Q2-M9XA"
            }
        }
    ],
    "links": {
        "first": null,
        "last": null,
        "prev": null,
        "next": "https://{school}.kolect.test/api/v1/payments?per_page=100&cursor=eyJwYWlkX2F0IjoiMjAyNi0wOS0xNSAwOTowMzoxMSIsImlkIjo0MTIsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0"
    },
    "meta": {
        "path": "https://{school}.kolect.test/api/v1/payments",
        "per_page": 100,
        "next_cursor": "eyJwYWlkX2F0IjoiMjAyNi0wOS0xNSAwOTowMzoxMSIsImlkIjo0MTIsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0",
        "prev_cursor": null
    }
}

Pages and polling

Pages are cursor-based. Follow links.next until it is null; never build a cursor yourself. To keep an ERP in step without re-reading history:

  1. The first time, walk every page with no filters and record each row by its reference.
  2. Keep the largest paid_at you have seen.
  3. On each later run, request ?paid_since= that value and walk the pages again.
  4. Upsert on reference. The cursor is inclusive, so the last row you saw comes back once more, which is harmless. A row you have never seen never goes missing.

Compare money on the *_minor integers. The decimal strings are for display.

One payment

GET https://{school}.kolect.test/api/v1/payments/{reference}

The same shape, for one reference. Case does not matter. A reference that is not a settled payment at this school is a 404, whatever else it may be.

{
    "data": {
        "reference": "UCP-2526-CSC-01J8ZK3Q9V",
        "gateway_reference": "CR-7f3a9c1e",
        "status": "successful",
        "currency": "NGN",
        "amount_minor": 1250000,
        "amount": "12500.00",
        "service_charge_minor": 100000,
        "service_charge": "1000.00",
        "total_charged_minor": 1350000,
        "total_charged": "13500.00",
        "channel": "whatsapp",
        "payment_method": "card",
        "payment_provider": "credo",
        "paid_at": "2026-09-15T09:03:11+00:00",
        "verified_at": "2026-09-15T09:03:14+00:00",
        "settled_at": "2026-09-16T02:00:00+00:00",
        "settled_amount_minor": 1250000,
        "student": {
            "matric_number": "CSC/2024/017",
            "first_name": "Adaobi",
            "last_name": "Okafor",
            "other_names": null,
            "email": "adaobi.okafor@example.edu.ng"
        },
        "collector": {
            "code": "CSC",
            "name": "Computer Science",
            "type": "department"
        },
        "collection": {
            "code": "DUES",
            "name": "Departmental Dues",
            "term": "full_session",
            "level": 200
        },
        "academic_session": {
            "name": "2025/2026",
            "short_code": "2526"
        },
        "receipt": {
            "number": "RCP-2526-CSC-000418",
            "verification_code": "K7Q2-M9XA",
            "verify_url": "https://kolect.online/verify/K7Q2-M9XA"
        }
    }
}

Fields

reference string
The payment reference. Unique, minted by the platform, printed on the student's bank statement. The key to reconcile on.
gateway_reference string or null
The gateway's own transaction reference.
status string
Always "successful" here. Present so the shape matches any later endpoint.
currency string
ISO 4217, "NGN".
amount_minor integer
What the collection charged, in kobo. Compare this, never the decimal.
amount string
The same amount as a decimal string, e.g. "12500.00". A string so no client ever parses it as a float.
service_charge_minor integer
The service charge the student paid on top, in kobo. Not part of what the collector receives.
service_charge string
The same, as a decimal string.
total_charged_minor integer
amount_minor plus service_charge_minor: what left the student's account.
total_charged string
The same, as a decimal string.
channel string
Where the student paid from: whatsapp, telegram, web, ussd or a staff channel.
payment_method string or null
What the gateway reported: card, bank_transfer, ussd and so on.
payment_provider string
The gateway that took it: credo or monnify.
paid_at string
When the gateway confirmed it, ISO 8601 in UTC. The value to keep for paid_since.
verified_at string or null
When the platform re-verified it against the gateway.
settled_at string or null
When the gateway paid it out to the collector's account, if known.
settled_amount_minor integer or null
What the gateway paid out, in kobo, if known.
student object
matric_number, first_name, last_name, other_names, email, as on the roster today.
collector object
code, name and type (faculty, department or other) of the unit that received the money.
collection object
code, name, term and level of the charge, as they stood when it was paid. Frozen: a later price change or promotion never rewrites it.
academic_session object
name and short_code of the session the charge belonged to.
receipt object or null
number, verification_code and a verify_url anyone can open to confirm the receipt.

Errors

Every error is JSON with a message.

401
No bearer token, or one this school did not issue or has revoked. The body says which is missing, never whether a token exists.
404
The reference is not a settled payment at this school, or the API was called on the platform's own address rather than the school's.
422
A filter did not validate. The body lists each field and why.
429
The token has gone over its budget for the minute. Wait for Retry-After.
405
Anything other than GET. The API does not write.

Limits and versions

  • Pages hold 100 rows unless per_page says otherwise, up to 500.
  • Each token may make 120 requests a minute. Over that, a 429 with Retry-After.
  • Times are ISO 8601 in UTC. Day filters are read in Africa/Lagos, the institution's time.
  • This is version 1, at /api/v1. Its fields will not change shape or meaning. New fields may be added; a breaking change would be a new version alongside it.

Getting a token

A school administrator issues one under Settings, Integrations, on the school's own address, named after the system that will hold it. It is shown once. If it is lost or leaked, they revoke it there and issue another.