Skip to main content

List applications

GET/applications

List applications

Returns your institution's applications, newest first, with cursor pagination. Optional filters: cycle (names, ids,current, or all), date range on submitted_at, and admission status. Available in json and csv formats.
Try it
Stored only in your browser (localStorage).
Query parameters
Page size (1–50).
Opaque cursor returned by a previous response.
current (all currently-open cycles), all, a published cycle name, or a cycle_id. Comma-separate up to 30.
Inclusive lower bound on submitted_at (YYYY-MM-DD).
Inclusive upper bound on submitted_at (YYYY-MM-DD).
Filter by admission decision or stage (applied to the fetched page).
Field groups to include: default | all | personal,application,payment,answers.

Parameters

NameInTypeDescription
limitqueryintegerPage size (1–50).
cursorquerystringOpaque cursor returned by a previous response.
formatquerystring
cyclequerystringcurrent (all currently-open cycles), all, a published cycle name, or a cycle_id. Comma-separate up to 30.
start_datequerystringInclusive lower bound on submitted_at (YYYY-MM-DD).
end_datequerystringInclusive upper bound on submitted_at (YYYY-MM-DD).
statusquerystringFilter by admission decision or stage (applied to the fetched page).
fieldsquerystringField groups to include: default | all | personal,application,payment,answers.
About status. Stage, decision, and enrolment live on the admission record, not the submission, so status is applied to the fetched page after the admissions join — it narrows the current page rather than the whole result set. cursor/has_next always track the underlying submission query.

Example response

{
  "code": 200,
  "has_next": true,
  "cursor": "g3kQabc…",
  "data": [
    {
      "id": "9f2abc",
      "personal": {
        "first_name": "Ada",
        "last_name": "Obi",
        "email": "ada@example.com",
        "phone": "+234…"
      },
      "application": {
        "institution_id": "inst_123",
        "program_id": "prog_eng",
        "program_name": "BSc Engineering",
        "cycle_id": "cyc_2026",
        "cycle_name": "2026 Intake",
        "stage": "submitted",
        "decision": "none",
        "decision_sent": false,
        "enrolled": false,
        "submitted_at": "2026-05-20T09:12:00.000Z"
      },
      "payment": {
        "paid": true,
        "amount": 50
      }
    }
  ]
}
curl -X GET 'https://api.uapply.africa/api/v1/applications' \
-H 'Authorization: Bearer YOUR_KEY'

Cycle resolution​

  • current → all currently-open cycles. Several cycles can be open at once; a cycle counts as open while today (Africa/Kigali calendar) falls inside its open-to-close window. If no cycle is open, this falls back to your institution's configured current cycle; if none is configured either, no cycle filter is applied.
  • all → every cycle.
  • Any other token is matched against published cycle names (case-insensitive); if it doesn't match a name it is treated as a raw cycle_id. Enumerate exact ids with GET /cycles.

Paging through every result​

cursor=""
while : ; do
resp=$(curl -s "https://api.uapply.africa/api/v1/applications?limit=50&cursor=$cursor" \
-H "Authorization: Bearer $UAPI_KEY")
echo "$resp" | jq '.data[]'
has_next=$(echo "$resp" | jq -r '.has_next')
[ "$has_next" = "true" ] || break
cursor=$(echo "$resp" | jq -r '.cursor')
done

Cursors are tied to the query that produced them — keep limit, cycle, and date filters identical across pages.

Exporting​

Pass format=csv to stream a CSV attachment. Nested objects (personal, application, payment) are flattened into columns, and the columns mirror exactly what the JSON response contains (so the fields selection applies to CSV too).

curl "https://api.uapply.africa/api/v1/applications?format=csv&cycle=current" \
-H "Authorization: Bearer $UAPI_KEY" -o applications.csv

Excel (.xlsx) export is temporarily unavailable — use csv for spreadsheets.