Consent Management

Collect TimeBack parental consent for a student from your own system. Instead of sending families through the in-app consent flow, your backend initiates the consent request, the platform emails each guardian a DocuSign signing link, and you poll for the result, all over machine-to-machine APIs.

Note: This guide covers the integration flow. See the API Reference for complete endpoint documentation, all parameters, and response schemas.

What This Provides

A partner system (for example, a school's own onboarding portal) can drive the full parental-consent lifecycle for an explicit student and guardian without the student ever opening the TimeBack App:

  • Initiate a consent request — the platform generates the DocuSign envelope and emails the guardian a signing link.
  • Track consent status through to granted by polling the student's consent records.
  • Record consent you collected out-of-band so it is reflected in TimeBack's audit trail.

The consent records form an immutable, append-only audit trail; each status change is a new record rather than an edit.

Prerequisites

  1. Register your App and obtain OAuth credentials — see Level 0: Register Your App and Authentication.

  2. Request the consent scopes for your M2M client (issued by the TimeBack Platform team, not self-serve):

    • consent.write — initiate a consent request and record a consent status.
    • consent.read — read a student's consent records.

    Each scope lives under the https://timeback-platform.trilogy.com/consent/scope resource server (for example, https://timeback-platform.trilogy.com/consent/scope/consent.write).

  3. Own the student's organization. The platform checks that your client owns the organization the student belongs to, and that consent management is enabled for that org. A caller that does not own the org, or whose org has consent management disabled, receives 403.

Exchange your credentials for an access token as described in Authentication, requesting the consent scopes:

curl -X POST https://platform.timeback.com/auth/1.0/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "<CLIENT_ID>:<CLIENT_SECRET>" \
  -d "grant_type=client_credentials&scope=https://timeback-platform.trilogy.com/consent/scope/consent.write https://timeback-platform.trilogy.com/consent/scope/consent.read"

Start the email consent flow for a student and one or more guardians:

POST /consent/1.0/students/{studentId}/consent-requests

Request body:

{
  "guardians": [
    { "id": "b1f6c2a0-7c2e-4b9a-9f3d-2a1c4e5d6f7a", "correctedFirstName": "Jane", "correctedLastName": "Doe" },
    { "id": "c2a7d3b1-8d3f-4c0b-a04e-3b2d5f6e7a8b" }
  ],
  "returnUrl": "https://your-portal.example.com/consent/done"
}
Field Type Description
guardians object[] One or more guardians to request consent from (at least one). Each guardian is emailed their own signing link.
guardians[].id string Guardian UUID. Required for each entry.
guardians[].correctedFirstName string Optional corrected legal first name. Must be supplied together with correctedLastName (both-or-neither); supplying only one rejects the whole request with 400.
guardians[].correctedLastName string Optional corrected legal last name. Must be supplied together with correctedFirstName.
returnUrl string Where the guardian's browser is redirected after they finish signing in DocuSign. Required — the platform hosts no landing page. Applies to every guardian in the request.
forceResend boolean Optional, defaults to false. Set true to intentionally re-email a guardian who was already emailed for this student. Applies to every guardian in the request. See Repeat calls and resending below.

The legacy { "guardianIds": ["..."] } shape is no longer accepted; send the guardians object array instead.

Correcting a guardian's name: supplying correctedFirstName + correctedLastName that differ from the guardian's stored name updates the name at the system of record before the signing envelope is generated, so the envelope (used for government-ID verification) carries the corrected legal name. If the guardian already had a live pending envelope with the old name, that envelope is voided and a new one is issued and emailed, so the guardian must use the newest signing link. Supplying a name identical to the stored one changes nothing.

Response: 202 Accepted with an empty body. The platform generates the DocuSign envelope and emails each guardian an HMAC-protected signing link. When a request names several guardians and some cannot be processed (for example, one has no active relationship to the student or no usable email on file), the call can still return 202 for the rest; the response does not report per-guardian outcomes, so confirm who was actually emailed by polling the records in Step 3.

Repeat calls and resending: this endpoint is safe to call repeatedly. The first call for a student+guardian emails the guardian. A repeat call reuses the existing DocuSign envelope and, by default, sends no further email, no matter how much time has passed, so retries and double-submits never spam the guardian. To deliberately re-email (for example, the guardian lost the message), set forceResend: true; a forced resend is still debounced by a short server-side window so a double-click cannot double-send. Guardians who have not yet signed are also chased automatically by scheduled reminder emails, so you do not need to resend just to remind them.

Error responses:

  • 400 — invalid input (for example, an empty guardians array, a guardian carrying only one of the two corrected-name fields, the legacy guardianIds shape, or a missing returnUrl); the student's consent is already granted ("Consent has already been granted"); or a named guardian has no active relationship to the student ("No active guardian-student relationship found").
  • 403 — your client does not own the student's organization, or consent management is disabled for it.
  • 404 — the student, or a named guardian user, does not exist. (A guardian who exists but is not related to the student is a 400, not a 404.)

This call requires the consent.write scope.

Step 2: The Guardian Signs (No Action Required From You)

Each guardian receives an email containing a signing link. When the guardian clicks it, the platform validates the HMAC-protected token and redirects the browser to a freshly generated DocuSign recipient-view page — no login required. After signing, the guardian lands on the returnUrl you supplied.

This step is handled entirely between the guardian and the platform; your integration does not call the redirect endpoint. You observe the outcome by polling the consent records in Step 3.

Read a student's consent history, most recent first:

GET /consent/1.0/students/{studentId}/records

Query parameters:

Parameter Type Description
limit integer Maximum records to return (1–100, default 10).
offset integer Number of records to skip for pagination (default 0).

Response (200):

{
  "records": [
    {
      "id": "f0e9d8c7-b6a5-4321-8f0e-1d2c3b4a5e6f",
      "studentId": "9a8b7c6d-5e4f-3210-9a8b-7c6d5e4f3210",
      "guardianId": "b1f6c2a0-7c2e-4b9a-9f3d-2a1c4e5d6f7a",
      "consentStatus": "granted",
      "occurredAtTime": "2026-06-30T10:15:00.000Z",
      "dateCreated": "2026-06-30T10:15:01.482Z",
      "dateLastModified": "2026-06-30T10:15:01.482Z",
      "metadata": { "envelopeId": "..." }
    }
  ],
  "offset": 0,
  "limit": 10,
  "total": 1
}

Poll this endpoint until the relevant record's consentStatus reaches granted (or a terminal status such as denied). This call requires the consent.read scope.

Status Meaning
pending A consent request is outstanding; the guardian has not yet signed. It stays pending until it is signed, declined, or explicitly voided.
granted Consent was given.
denied The guardian declined consent.
expired Not produced automatically by the platform. A request that lapses unsigned stays pending; expired appears only if you record it yourself via the record endpoint below.
voided The request was invalidated before completion — superseded by a newer request, a name correction, or a sibling guardian granting. Voided records carry metadata.supersededBy and metadata.originalEnvelopeId.
withdrawn Previously granted consent was later revoked (see Recording Consent Collected Elsewhere).

Poll for a terminal outcome (granted or denied); do not wait for expired, which the platform never writes on its own. A long-lived pending means the guardian still has not signed — they are chased by automatic reminder emails, so you do not need to resend just to remind them.

When a request targets several guardians, each guardian produces its own record; query the records to see who has responded.

Records Awaiting a Guardian

A pending record may have a null guardianId together with metadata.consentMethod of "awaiting_guardian". This represents a student whose consent is being tracked before a specific guardian has been identified, as opposed to an ordinary email-flow pending record, which carries the guardian's guardianId. This is also the only shape in which the record endpoint accepts a null guardian.

Record Metadata

metadata is free-form; the platform commonly populates these keys on records you read:

Key Meaning
consentMethod How consent was gathered: email, in_person, or awaiting_guardian.
docusignEnvelopeId The DocuSign envelope backing an email-flow request.
docusignStatus The last known DocuSign envelope status.
emailConsentInitiatedAt When the email consent flow was initiated.
returnUrl The post-signing redirect URL supplied when the request was initiated.
supersededBy On a voided record, why it was superseded (for example, a newer request or a name correction).
originalEnvelopeId On a voided record, the envelope that was superseded.

Additional keys may be present; treat metadata as an open, free-form object.

If you obtained parental consent out-of-band and want it reflected in TimeBack's audit trail, write a record directly:

POST /consent/1.0/students/{studentId}/records

Request body:

{
  "consentStatus": "granted",
  "occurredAtTime": "2026-06-30T09:00:00.000Z",
  "guardianId": "b1f6c2a0-7c2e-4b9a-9f3d-2a1c4e5d6f7a",
  "metadata": { "source": "school-onboarding-portal" }
}
Field Type Description
consentStatus enum One of the status values above. Required.
occurredAtTime ISO 8601 When the consent status change occurred. Required.
guardianId UUID, nullable The guardian who provided consent. Required, except when recording a pending record whose metadata.consentMethod is "awaiting_guardian" — the only case a null guardian is accepted.
metadata object, nullable Free-form audit context (for example, the source system or a DocuSign envelope ID).

Response: 201 Created. This call requires the consent.write scope. Because the record store is append-only, this adds a new record rather than editing an existing one.

Requirements and errors:

  • When guardianId is supplied, the guardian must have an active relationship to the student, otherwise 400.
  • A null guardianId is rejected with 400 unless the record is pending with metadata.consentMethod: "awaiting_guardian".
  • 403 — your client does not own the student's organization.
  • 404 — the student, or a supplied guardian user, does not exist.

Revoking consent: there is no separate revoke endpoint. To reflect a revocation, record a new withdrawn status here; because the store is append-only, this supersedes the prior granted record without deleting it.

End-to-End Example

# 1. Get an access token with the consent scopes
ACCESS_TOKEN=$(curl -s -X POST https://platform.timeback.com/auth/1.0/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "<CLIENT_ID>:<CLIENT_SECRET>" \
  -d "grant_type=client_credentials&scope=https://timeback-platform.trilogy.com/consent/scope/consent.write https://timeback-platform.trilogy.com/consent/scope/consent.read" \
  | jq -r .access_token)

# 2. Initiate the consent request for a student + guardian
curl -X POST "https://platform.timeback.com/consent/1.0/students/${STUDENT_ID}/consent-requests" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "guardians": [{ "id": "'"${GUARDIAN_ID}"'" }],
    "returnUrl": "https://your-portal.example.com/consent/done"
  }'
# → 202 Accepted; the guardian is emailed a signing link.

# 3. Poll status until granted
curl "https://platform.timeback.com/consent/1.0/students/${STUDENT_ID}/records?limit=10" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}"
# → inspect records[].consentStatus

Level 0: Register Your App

Register your App to get an App ID and OAuth credentials — the prerequisite for requesting consent scopes.

Authentication

Exchange your OAuth credentials for access tokens to call the consent APIs.

API Reference

Interactive API reference with full request/response schemas for the consent endpoints.