Update applications
PATCH
/applications/updateBulk-update admission state
Updates
stage, decision, and/or enrolled on the admission record for each submission id. Updates are batched atomically. At least one of the three fields must be present.Try it
Stored only in your browser (localStorage).
Body parameters
Submission ids to update — comma-separate multiple ids.
Free-form stage string (lowercased server-side); coordinate values with your dashboard's pipeline.
Admission decision to set.
Whether the applicant is enrolled.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idsrequired | body | array | Submission ids to update — comma-separate multiple ids. |
stage | body | string | Free-form stage string (lowercased server-side); coordinate values with your dashboard's pipeline. |
decision | body | string | Admission decision to set. |
enrolled | body | boolean | Whether the applicant is enrolled. |
Trial key simulates. With the public
Does not email applicants. This endpoint updates admission data only. To send a decision letter and notify the student, use the dashboard's Send decision flow — it records a
uap_sandbox_… key this endpoint validates the request but writes nothing — the response carries "simulated": true and a would_return object showing exactly what a live call would have produced. Only a real uap_live_ key actually changes admission data.Does not email applicants. This endpoint updates admission data only. To send a decision letter and notify the student, use the dashboard's Send decision flow — it records a
decisions document and dispatches the email.Example response
{
"code": 200,
"simulated": true,
"message": "Trial key: no data was changed. `would_return` below is exactly what a live uap_live_ key would have returned.",
"would_return": {
"code": 200,
"updated_count": 1,
"failed_count": 0,
"failed_ids": [],
"updates": {
"decision": "accepted",
"enrolled": true
}
}
}curl -X PATCH 'https://api.uapply.africa/api/v1/applications/update' \
-H 'Authorization: Bearer YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"ids":["sandbox-app-001"],"decision":"accepted"}'
Behaviour
- Each id is resolved to its admission record in
partnerships/{institution}/admissions. Because that subcollection is scoped to your institution, ownership is implicit — ids that have no admission under your institution are reported infailed_ids. decisionacceptsaccepted,waitlisted, orrejected.enrolledis a boolean.stageis a free-form string (lowercased server-side); coordinate values with your dashboard's stage pipeline.
Sending a decision
POST /applications/{id}/decision sends an admission decision for one of your
applications and notifies the applicant, the same as the dashboard's
Send decision flow. Use it when the decision is made in your own system.
curl -X POST "https://api.uapply.africa/api/v1/applications/sandbox-app-001/decision" \
-H "X-API-Key: $UAPPLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"decision_status": "accepted",
"decision_message": "Congratulations, we are pleased to offer you a place.",
"external_reference": "SIS-2026-00123"
}'
decision_statusis required:accepted,rejected, orwaitlisted.decision_letter(HTML, sanitised on our side) anddecision_messageare optional.external_referenceis optional, at most 128 characters, and is stored on the decision so you can match it to your own records.- A successful call returns
201with{ "code": 201, "decision_id": "…", "simulated": false }. - A decision can be sent once per application. A second call returns
409with"error": "decision_already_sent". - An id that is not one of your institution's applications, or an application
with no admission record yet, returns
404with"error": "not_found". - A live key can send decisions only after you turn on Can send admission
decisions for it in Settings > API (off by default, and off again after a
rotation). Otherwise the call returns
403with"error": "decisions_not_enabled_for_key".
Trial keys simulate. With the public uap_sandbox_… key the request is
validated and the application is looked up, but nothing is sent. The response
is 200 with { "code": 200, "decision_id": null, "simulated": true }.