The EduPay API lets the school's other systems — ERP, CRM, website, learning platform, BI — read and write the school's data in EduPay: catalog, students, enrollments, contracts and charges. It also notifies those systems the moment something happens, such as a confirmed payment.
Each key belongs to one school and only sees that school's data.
What you can do
- Read the catalog (offerings, tracks, cohorts, payment plans and sales pages), students, enrollments, contracts (with the PDF) and installments, with the payment details.
- Write: create and update students, create and cancel enrollments, and issue a second copy of an installment. An enrollment created through the API follows the same path as an enrollment made in the panel: it generates the installments and the contract, adds the student to Moodle and issues the charge.
- Receive webhooks for students, enrollments, contracts and installments, signed so you can check they came from EduPay.
- Open the student portal already signed in, from another system, with a link that works only once.
The Moodle integration has its own plugin and its own routes. It is described in Moodle integration.
Addresses
| What | Address |
|---|---|
| API | https://edupay.estudiosite.com/api/v1 |
| OpenAPI specification | https://edupay.estudiosite.com/api/v1/openapi.json |
| This documentation | https://edupay.estudiosite.com/en/desenvolvedores |
1. Turn on the API and create the key
This is done by the school's account owner in EduPay:
- Sign in to the panel and open Integrations → API Tokens.
- In the Public API (v1) box, click Turn API on. The API starts turned off for every school. Moodle works with it on or off.
- Click Create token, give it a name that says where the key will be used (e.g. "ERP Financeiro") and choose the permissions. The ready-made bundles help: Read only or Read and write. See Permissions.
- Copy the key. It starts with
edp_and is shown only once. EduPay keeps only a fingerprint of it.
Treat the key like a password when you hand it to whoever builds the integration. It never goes in a website, a mobile app or any code that runs in the browser.
2. First call
Store the key in a variable and call /me, which answers any key and shows which school it belongs to:
export EDUPAY_KEY="edp_..."
curl https://edupay.estudiosite.com/api/v1/me \
-H "Authorization: Bearer $EDUPAY_KEY"
{
"data": {
"school": { "name": "Colégio Modelo", "country": "BR", "currency": "BRL", "timezone": "America/Sao_Paulo" },
"token": { "name": "ERP Financeiro", "prefix": "edp_7d2e9f01...", "scopes": ["students:read", "billing:read"], "expires_at": null }
}
}
If you get 401, the key is wrong, expired or revoked. If you get 403 with code equal to api_disabled, the API is still turned off for the school.
3. A real query
Overdue installments, 50 per page:
curl "https://edupay.estudiosite.com/api/v1/installments?status=overdue&limit=50" \
-H "Authorization: Bearer $EDUPAY_KEY"
The response has data (the list) and meta.next_cursor. For the next page, repeat the call with cursor= set to that value. Details in Errors and limits.
Conventions for the whole API
- JSON both ways. Writes send
Content-Type: application/json. - Money in cents, as an integer, always with the currency next to it (
"amount": 45000, "currency": "BRL"is R$ 450.00). - Date and time in ISO 8601, in UTC (
2026-11-10T13:00:00Z). Dates without time (due date, birth date) inYYYY-MM-DD. - Errors in
application/problem+json, with acodethat does not change between versions. Decide by thecode, not by the text. - Language of the messages:
Accept-Languageheader withpt-BR,enores. Without it, Portuguese. - Every response has the
X-Request-Idheader. Give this value to support when you need help with a call.
Test without disrupting the school
EduPay has no separate test environment: the key works with the school's real data. So:
- start with a read-only key and check everything before asking for write permission;
- before writing, agree with the school on a test student and a test cohort. An enrollment created through the API issues real charges, just like one made in the panel;
- use
external_idandIdempotency-Keyfrom day one (see Students and enrollments). That way, repeating a request never duplicates anything.
Next steps
- Access keys: replace the key without taking the integration down.
- Students and enrollments: sync without duplicates.
- Webhooks: know the moment a payment comes in.
- Reference: every route, with examples.