Skip to Content
Portal API (v1)

Reading data

Read seasons, students, season enrollments, internship results and approved companies.

Paths below are relative to https://<trường>.<tên-miền-nền-tảng>/integration/v1.

MethodPathScope
GET/seasonsseasons:read
GET/seasons/{id}seasons:read
GET/studentsstudents:read
GET/students/{studentCode}students:read
GET/seasons/{id}/enrollmentsenrollments:read
GET/seasons/{id}/resultsresults:read
GET/seasons/{id}/companiescompanies:read

Seasons

GET /seasons returns every season of the school (up to 500, oldest first). Filter by term id: ?externalId=HK1-2026.

{
  "data": [
    {
      "id": "k3v9x2m1q8w7e6r5t4y3u2i1",
      "externalId": "HK1-2026",
      "name": "Đợt thực tập học kỳ 1 năm học 2026-2027",
      "status": "open",
      "openedAt": "2026-09-01T01:00:00.000Z",
      "closesAt": "2027-01-15T16:59:59.000Z",
      "closedAt": null,
      "updatedAt": "2026-11-02T03:12:44.000Z"
    }
  ]
}

status: open, upcoming (not opened yet) or closed. A school has at most one open season.

Students

GET /students returns the school's students in pages (see Paging).

ParameterMeaning
limit, cursorPaging
updatedSinceOnly students changed since this instant (ISO 8601)
statusactive or blocked
seasonA season id: only students in that season
{
  "data": [
    {
      "id": "p0o9i8u7y6t5r4e3w2q1a2s3",
      "studentCode": "SV2026001",
      "externalId": "U-1001",
      "name": "Nguyễn Văn An",
      "email": "[email protected]",
      "signIn": "google",
      "loginName": null,
      "status": "active",
      "createdAt": "2026-09-02T02:00:00.000Z",
      "updatedAt": "2026-11-02T03:12:44.000Z"
    }
  ],
  "next": "eyJhZnRlciI6MTIzfQ"
}
  • signIn: google (Google account matching email) or password (loginName and password).
  • email is null for a login-name account without a real email.

GET /students/{studentCode} returns one student in data, or 404.

Season enrollments

GET /seasons/{id}/enrollments, in pages:

{
  "data": [
    {
      "id": "z1x2c3v4b5n6m7a8s9d0f1g2",
      "externalId": null,
      "season": "k3v9x2m1q8w7e6r5t4y3u2i1",
      "student": { "id": "p0o9i8u7y6t5r4e3w2q1a2s3", "studentCode": "SV2026001", "externalId": "U-1001", "name": "Nguyễn Văn An" },
      "placed": false,
      "admittedAt": "2026-09-02T02:00:00.000Z"
    }
  ],
  "next": null
}

placed: whether the student has an internship in this season.

Internship results

GET /seasons/{id}/results returns, for each student in the season, the confirmed placement:

{
  "data": [
    {
      "student": { "id": "p0o9i8u7y6t5r4e3w2q1a2s3", "studentCode": "SV2026001", "externalId": "U-1001", "name": "Nguyễn Văn An" },
      "season": "k3v9x2m1q8w7e6r5t4y3u2i1",
      "placed": true,
      "company": { "id": "c8d7e6f5g4h3j2k1l0m9n8b7", "name": "Công ty Cổ phần Ví dụ" },
      "acceptedAt": "2026-10-05T08:30:00.000Z",
      "pendingApplications": 0
    }
  ],
  "next": null
}
  • placed: false and company: null: no placement yet.
  • pendingApplications: applications waiting for the company or for the student's answer.

Approved companies

GET /seasons/{id}/companies returns the companies the school approved for the season (no paging):

{
  "data": [
    {
      "id": "c8d7e6f5g4h3j2k1l0m9n8b7",
      "name": "Công ty Cổ phần Ví dụ",
      "shortName": "Ví dụ",
      "sponsor": false,
      "hiringOpen": true,
      "maximumWaitingApplications": 30,
      "maximumAcceptedStudents": 10
    }
  ]
}

hiringOpen: the company still accepts applications. The two maximums are null when unlimited.

On this page