Daakiaa API· Developer referencev1

Overview

The Daakiaa API lets other software (a school or college system, an HR or training platform…) set up an organization on Daakiaa: its domain, mailboxes for its people, and online classes or sessions with personal join links and attendance.

It is a JSON API over HTTPS. Every address below starts with the base URL, which is your Daakiaa mail address followed by /v1/api:

https://mail.<your Daakiaa domain>/v1/api

Send request bodies as JSON with Content-Type: application/json. Fields the API does not know are refused (400), so a typo never goes unnoticed. Times are ISO 8601 with a time zone, e.g. 2026-10-12T09:30:00+05:30.

Authentication

Every request carries an API key in the Authorization header:

curl -H "Authorization: Bearer dk_org_…" https://mail.<domain>/v1/api/me

There are two kinds of key:

  • Partner keys (dk_partner_…), for software companies that serve many organizations. Made by a Daakiaa partner in the partner console (API & Integrations). A partner key can create organizations and then act for any organization it created, at /v1/api/orgs/{orgID}/….
  • Organization keys (dk_org_…), for one organization. Made by its administrator in the admin console (Admin → API & Integrations), or by a partner withPOST /orgs/{orgID}/keys. An organization key acts only for its own organization, at /v1/api/org/….

A key is shown once, when it is made; Daakiaa keeps only a fingerprint of it. Store it like a password, on your server only: never in an app, a web page or a repository. If a key is lost or leaked, revoke it (it stops working at once) and make a new one. Each key's last use and address are shown next to it.

Errors & limits

Errors come back as JSON with a readable message: {"error": "…"}.

400The request is not valid (a missing or unknown field, a bad value). The message says what to fix.
401No key, a malformed key, or a key that is unknown or revoked (or whose organization or partner is suspended).
403The key is valid but may not do this (e.g. an organization key calling a partner-only endpoint).
404Not found, including an organization that is not yours: others look the same as missing ones.
429Too many requests. Wait for the Retry-After header (seconds) and try again.

Rate limit: 600 requests a minute per key. Use the bulk endpoints for large imports, and retry after a 429 or a 5xx with a growing delay. Repeated wrong keys from one address are refused for a while.

Partner endpoints

Only for partner keys.

  • GET/v1/api/me

    Which key this is (kind, name, prefix; for an organization key, its organization). Use it to test a key. Works with both kinds of key.

  • POST/v1/api/orgs

    Create an organization (on the Education plan, or the plan agreed with Daakiaa) with its first admin mailbox.

    {
      "name": "Green Valley College",
      "contact_email": "office@greenvalley.edu.in",
      "domain": "greenvalley.edu.in",
      "admin": { "name": "Anita Rao", "local_part": "principal" }
    }
  • GET/v1/api/orgs

    The organizations this partner key created.

  • POST/v1/api/orgs/{orgID}/keys

    Make an organization key for one of your organizations (shown once in the response).

    { "name": "Campus app" }

Organization endpoints

Everything an organization can do is reached two ways, with the same paths after the prefix:

  • with an organization key: /v1/api/org/… (e.g. /v1/api/org/people)
  • with a partner key, for one of its organizations: /v1/api/orgs/{orgID}/…

A person is referred to ({ref}) by their email address, or by your own id as ext:<external_id>, e.g. /people/ext:ADM-2024-0193. Using your ids means you never have to store Daakiaa's.

Domains

An organization's mail uses its own domain once the DNS records the API returns are in place.

  • GET.../org/domains

    The organization's domains, with their status and the DNS records still needed.

  • POST.../org/domains

    Add a domain.

    { "domain": "greenvalley.edu.in" }
  • POST.../org/domains/{domain}/verify

    Check the domain's DNS records now; it becomes verified when they are in place.

Storage

On the Education plan the whole organization gets 100 GB shared by everyone; the default mailbox size decides how it is shared out.

  • GET.../org/storage

    Space used and available for the whole organization.

  • PUT.../org/storage/default

    The default mailbox size for new people.

    { "quota_bytes": 2147483648 }

People

Its people (teachers, students and staff), each with a mailbox. Passwords are returned only in the response that set them.

  • POST.../org/people

    Create a person's mailbox (role teacher, student or staff; use staff for everyone who is neither). Without a password, one is generated and returned once.

    {
      "role": "student",            // teacher | student | staff
      "name": "Rohan Mehta",
      "local_part": "rohan.mehta",  // optional: made from the name
      "external_id": "ADM-2024-0193", // your system's id
      "grade": "8",
      "section": "B",
      "password": "…",              // optional
      "quota_bytes": 1073741824     // optional
    }
  • POST.../org/people/bulk

    Create many people in one call (a list of the same objects). Each one succeeds or fails on its own; the response says which.

  • GET.../org/people?role=&grade=&section=&q=

    List people; filter by role, grade, section, or search names and addresses with q.

  • GET.../org/people/{ref}

    One person.

  • PATCH.../org/people/{ref}

    Change a person (name, grade, section, quota, status…). Send only what changes.

  • DELETE.../org/people/{ref}

    Delete a person's mailbox.

  • POST.../org/people/{ref}/password

    Set a new password (or omit it to have one generated and returned once).

    { "password": "…" }

Classes

Online classes, lectures or training sessions run on Daakiaa Meet. Teachers host; students join with their personal links.

  • POST.../org/classes

    Schedule an online class or session (a Daakiaa Meet meeting) with its teacher (host) and students (participants).

    {
      "title": "Science · Class 8B",
      "teacher": "ext:T-0042",             // a person ref
      "co_teachers": ["sunita@greenvalley.edu.in"],
      "students": ["ext:ADM-2024-0193"],   // or set grade + section
      "grade": "8",
      "section": "B",
      "scheduled_at": "2026-10-12T09:30:00+05:30",
      "duration_min": 40,
      "start_mode": "…",                   // when students may join
      "controls": { … }                    // classroom controls (mic, camera, chat…)
    }
  • GET.../org/classes?from=&to=&teacher=&student=

    The organization's classes (from/to: a date or RFC 3339 time; up to 500). Each has a status: scheduled, live, ended, missed (nobody came, or its time passed unstarted) or expired.

  • GET.../org/classes/{code}

    One class with its roster (without links).

  • PATCH.../org/classes/{code}

    Change a class: title, scheduled_at ("" clears it), duration_min, start_mode, host_ends, controls. Time and start mode only before it starts; controls apply live.

  • DELETE.../org/classes/{code}

    Cancel a class that hasn't started and nobody has joined.

  • PUT.../org/classes/{code}/roster

    Replace the roster {teacher, co_teachers, students, grade, section}; fields you leave out stay as they are. The main teacher changes only before the start.

  • POST.../org/classes/{code}/roster

    Add people (same body as PUT).

  • POST.../org/classes/{code}/roster/remove

    Remove people {people: [refs]}; anyone removed who is in the class right now is taken out. The main teacher can't be removed.

  • GET.../org/classes/{code}/links

    Everyone's personal join link: {email, name, role, external_id, link}.

  • POST.../org/classes/{code}/links

    Links for some people {people: [refs]}. The teacher's link makes them the host. Send each person only their own link; removing someone from the roster stops their link.

  • GET.../org/classes/{code}/attendance

    Per roster person: joined, first/last seen, seconds, joins, camera/mic/screen/talk seconds, chat messages, reactions, hand raises; plus absent and others. Add ?format=xlsx for an Excel report.

A typical flow:

# 1. schedule the class
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"title":"Science · 8B","teacher":"ext:T-0042","grade":"8","section":"B",
       "scheduled_at":"2026-10-12T09:30:00+05:30","duration_min":40}' \
  https://mail.<domain>/v1/api/org/classes

# 2. personal join links, to show each person in your app
curl -X POST -H "Authorization: Bearer $KEY" https://mail.<domain>/v1/api/org/classes/{code}/links

# 3. after the class
curl -H "Authorization: Bearer $KEY" https://mail.<domain>/v1/api/org/classes/{code}/attendance

Good to know

  • Students' mail stays inside the organization (Education plan, on by default; its admin can turn it off): students write to and receive mail from their own organization only.
  • Storage: the Education plan is 100 GB shared by the whole organization, not per person.
  • The older paths /school/…, /schools/… and keys starting dk_school_ keep working.
  • Responses may gain new fields over time; ignore the ones you do not use.
  • Keep keys on your server. Make one key per program or environment, so one can be revoked without the others.
  • Every call is logged with the key and the caller's address; administrators see the key's last use in their console.