API reference

API Reference

Welcome to the Okta Partners platform API reference. Once your app is approved and a tenant installs it, this API lets your app read and write Okta data — strictly within the scopes that tenant explicitly granted.

The runtime API is hosted by **okta-web** (the core platform app); every request hits the `/apps` path under the base URL. The partner platform (okta-partners) is where you register your app, pick scopes, and manage versions and webhooks.

The API is REST over HTTPS, exchanges JSON (UTF-8), and uses standard HTTP status codes. Every read and write is isolated per tenant and protected by a named scope.

Your first call

curl https://getokta.io/api/apps/whoami \
  -H "Authorization: Bearer $OKTA_PARTNER_TOKEN" \
  -H "Accept: application/json"

Base URL

The runtime API is hosted by okta-web under the following path:

https://getokta.io/api/apps

Sandbox environment:

https://dev.getokta.io/api/apps

Authentication

Every request authenticates with a per-installation **Bearer token**. The token is issued automatically when a tenant installs your app; it is bound to a (tenant, app) pair and carries the granted scopes.

Authorization: Bearer <installation_token>
  • Never embed the token in front-end code or a public repo — store it as a server-side secret (e.g. `OKTA_PARTNER_TOKEN`).
  • The token is rotatable from the partner dashboard; external apps receive the new token over the bridge without a redeploy.
  • A missing or invalid token returns `401 Unauthorized`. A valid token lacking the required scope returns `403 Forbidden`.

Verify your token

curl https://getokta.io/api/apps/whoami \
  -H "Authorization: Bearer $OKTA_PARTNER_TOKEN"
# → { "tenant_id": 42, "module": "your-app", "scopes": [ ... ] }

Scopes

Every piece of data is protected by a scope shaped `..`. Partners get exactly two actions: `read` and `write`. Delete is never granted to partners. You pick scopes when creating the app; the tenant approves them on install.

Scope Description
education.students.read Read students
education.students.write Create / update students
education.guardians.read Read guardians
education.subjects.read Read subjects
education.grades.read Read grades
education.sections.read Read sections
education.academic_years.read Read academic years
education.terms.read Read terms
employees.directory.read Read employee directory
reports.builder.read Report catalog / run
notifications.providers.send Send via a notification provider

Endpoints

All paths are relative to the base URL above. Write endpoints (POST/PATCH) require the matching scope.

Identity

GET /whoami no scope Current installation info (tenant, app, scopes).
GET https://getokta.io/api/apps/whoami

Current installation info (tenant, app, scopes).

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: none
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_a43d
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Students

GET /education/students education.students.read List students (paginated).
GET https://getokta.io/api/apps/education/students

List students (paginated).

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.students.read
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_b079
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Query Params

page integer

Page number (1-based).

per_page integer

Items per page (max 100).

search string

Optional free-text search.

GET /education/students/{id} education.students.read A single student.
GET https://getokta.io/api/apps/education/students/{id}

A single student.

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.students.read
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_5905
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Path Params

id integer required

The resource id in Okta.

POST /education/students education.students.write Create a student.
POST https://getokta.io/api/apps/education/students

Create a student.

  • Rate Limit: MODERATE
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.students.write
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_0ec3
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Body Params

full_name string required

Student's full name.

national_id string

National / residency id.

birth_date date

Birth date (YYYY-MM-DD).

gender enum

male or female.

grade_id integer

Grade id.

section_id integer

Section id.

guardian_id integer

Guardian id.

PATCH /education/students/{id} education.students.write Update a student.
PATCH https://getokta.io/api/apps/education/students/{id}

Update a student.

  • Rate Limit: MODERATE
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.students.write
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_e45a
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Path Params

id integer required

The resource id in Okta.

Body Params

full_name string

Student's full name.

national_id string

National / residency id.

birth_date date

Birth date (YYYY-MM-DD).

gender enum

male or female.

grade_id integer

Grade id.

section_id integer

Section id.

guardian_id integer

Guardian id.

Guardians

GET /education/guardians education.guardians.read List guardians.
GET https://getokta.io/api/apps/education/guardians

List guardians.

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.guardians.read
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_aac5
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Query Params

page integer

Page number (1-based).

per_page integer

Items per page (max 100).

search string

Optional free-text search.

GET /education/guardians/{id} education.guardians.read A single guardian.
GET https://getokta.io/api/apps/education/guardians/{id}

A single guardian.

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.guardians.read
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_4be0
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Path Params

id integer required

The resource id in Okta.

POST /education/guardians education.guardians.write Create a guardian.
POST https://getokta.io/api/apps/education/guardians

Create a guardian.

  • Rate Limit: MODERATE
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.guardians.write
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_8da4
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Body Params

full_name string required

Guardian's full name.

phone string required

Phone in E.164 format.

email string

Email address.

relation enum

father | mother | other.

PATCH /education/guardians/{id} education.guardians.write Update a guardian.
PATCH https://getokta.io/api/apps/education/guardians/{id}

Update a guardian.

  • Rate Limit: MODERATE
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.guardians.write
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_4ca6
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Path Params

id integer required

The resource id in Okta.

Body Params

full_name string

Guardian's full name.

phone string

Phone in E.164 format.

email string

Email address.

relation enum

father | mother | other.

Curriculum

GET /education/subjects education.subjects.read Subjects.
GET https://getokta.io/api/apps/education/subjects

Subjects.

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.subjects.read
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_bd8c
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Query Params

page integer

Page number (1-based).

per_page integer

Items per page (max 100).

search string

Optional free-text search.

POST /education/subjects education.subjects.write Create a subject (idempotent).
POST https://getokta.io/api/apps/education/subjects

Create a subject (idempotent).

  • Rate Limit: MODERATE
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.subjects.write
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_96e0
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Body Params

name string required

Subject name.

code string

Subject code.

GET /education/grades education.grades.read Grades.
GET https://getokta.io/api/apps/education/grades

Grades.

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.grades.read
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_7d9a
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Query Params

page integer

Page number (1-based).

per_page integer

Items per page (max 100).

search string

Optional free-text search.

GET /education/sections education.sections.read Sections.
GET https://getokta.io/api/apps/education/sections

Sections.

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.sections.read
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_1d44
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Query Params

page integer

Page number (1-based).

per_page integer

Items per page (max 100).

search string

Optional free-text search.

GET /education/academic-years education.academic_years.read Academic years.
GET https://getokta.io/api/apps/education/academic-years

Academic years.

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.academic_years.read
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_faa5
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Query Params

page integer

Page number (1-based).

per_page integer

Items per page (max 100).

search string

Optional free-text search.

GET /education/terms education.terms.read Terms.
GET https://getokta.io/api/apps/education/terms

Terms.

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: education.terms.read
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_df6c
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Query Params

page integer

Page number (1-based).

per_page integer

Items per page (max 100).

search string

Optional free-text search.

Employees

GET /employees/directory employees.directory.read Employee directory.
GET https://getokta.io/api/apps/employees/directory

Employee directory.

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: employees.directory.read
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_c6a4
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Query Params

page integer

Page number (1-based).

per_page integer

Items per page (max 100).

search string

Optional free-text search.

GET /employees/directory/{id} employees.directory.read A single employee.
GET https://getokta.io/api/apps/employees/directory/{id}

A single employee.

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: employees.directory.read
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_5c8f
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Path Params

id integer required

The resource id in Okta.

POST /employees/directory employees.directory.write Add an employee (idempotent).
POST https://getokta.io/api/apps/employees/directory

Add an employee (idempotent).

  • Rate Limit: MODERATE
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: employees.directory.write
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_0fe2
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Body Params

full_name string required

Employee's full name.

job_title string

Job title.

email string

Email address.

Reports

GET /reports/builder reports.builder.read Catalog of available reports.
GET https://getokta.io/api/apps/reports/builder

Catalog of available reports.

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: reports.builder.read
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_5f23
    A stable identifier for this endpoint — quote it to support to speed up tracing.

POST /reports/builder/{key}/run reports.builder.read Run a report (idempotent).
POST https://getokta.io/api/apps/reports/builder/{key}/run

Run a report (idempotent).

  • Rate Limit: HEAVY
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: reports.builder.read
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_8dd1
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Path Params

key string required

Report key from the catalog.

Body Params

parameters object

Report parameters (report-specific).

Notifications

GET /notifications/capabilities notifications.providers.send Notification channel capabilities.
GET https://getokta.io/api/apps/notifications/capabilities

Notification channel capabilities.

  • Rate Limit: LIGHT
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: notifications.providers.send
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_f406
    A stable identifier for this endpoint — quote it to support to speed up tracing.

POST /notifications/send notifications.providers.send Send a message (idempotent).
POST https://getokta.io/api/apps/notifications/send

Send a message (idempotent).

  • Rate Limit: MODERATE
    How heavily this call counts against your quota: LIGHT < MODERATE < HEAVY.
  • Permission needed: notifications.providers.send
    The scope the tenant must grant your app before this call is allowed.
  • Reference Code: srv_3458
    A stable identifier for this endpoint — quote it to support to speed up tracing.

Body Params

recipient string required

Recipient (phone or user id).

message string required

Message body.

channel string

Specific channel (optional).

The full, always-current list lives in the auto-generated OpenAPI 3.1 spec: /docs/openapi.json · /docs/postman_collection.json

Pagination

List endpoints are paginated. Use `?page=2&per_page=50` (max 100 per page).

{
  "data": [ ... ],
  "total": 1242,
  "per_page": 20,
  "current_page": 1,
  "last_page": 63
}

Idempotency

Write operations (POST/PATCH) accept an optional header. The same key within 24 hours replays the same stored response — so if your side times out, retrying will not create a duplicate record.

Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000

Errors

Errors are returned as a consistent JSON envelope with the appropriate HTTP status code.

{
  "message": "The given scope is not granted for this installation.",
  "error": "scope_not_granted",
  "scope": "education.students.write"
}
Status Name Description
400 Bad Request Malformed or missing request body.
401 Unauthorized Missing or invalid token.
403 Forbidden Valid token, but the required scope is not granted.
404 Not Found Resource not found within the tenant scope.
409 Conflict Idempotency conflict or inconsistent state.
422 Unprocessable Entity Field validation failed.
429 Too Many Requests Rate limit exceeded.
5xx Server Error Transient error — retry with backoff.

Rate limits

Every response carries headers telling you the remaining budget. On exceed, you get `429` with `Retry-After` (seconds). Honor exponential backoff on retry.

Header Description
X-RateLimit-Limit Ceiling for the window.
X-RateLimit-Remaining Remaining in the current window.
Retry-After Seconds until a new request is allowed (with 429).

Webhooks

External apps receive platform events via signed webhooks. Each webhook is an HTTP POST with a JSON body, signed with HMAC-SHA256 over the envelope `.`.

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "event": "education.students.created",
  "tenant_id": 42,
  "created_at": "2026-04-26T10:30:15+03:00",
  "data": { "student": { "id": 123, "full_name": "..." } }
}
Header Description
X-Okta-Event Event name.
X-Okta-Delivery-Id UUID stable across retries (for dedup).
X-Okta-Timestamp Unix timestamp at signing.
X-Okta-Signature HMAC-SHA256 signature (hex).

Verify the signature

$expected = hash_hmac(
    'sha256',
    $request->header('X-Okta-Timestamp').'.'.$request->getContent(),
    $YOUR_WEBHOOK_SECRET,
);

if (! hash_equals($expected, $request->header('X-Okta-Signature'))) {
    return response('invalid signature', 401);
}
  • Check `X-Okta-Timestamp` is within the last 5 minutes, and store `X-Okta-Delivery-Id` for at least 15 minutes to reject replays.
  • Respond 2xx within 10 seconds. For long work, accept with 202 immediately and process asynchronously.
  • Retry backoff: 30s → 2m → 10m → 1h → 6h, after which the delivery is marked failed and surfaces on the Webhook Deliveries page in the partner dashboard.

More resources

This reference is a practical summary. For the full picture (integration types, app lifecycle, the manifest, the policy scanner) see the developer guide.