> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coraltalk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Student sign-in token

> Provision a student and return a Clerk sign-in token for custom domain exams via the Platform API.

# Student sign-in token

Provision or look up a student in a class and return a short-lived Clerk **sign-in token**. Use this when students take exams on a [custom domain](/coraltalk-apis/custom-domains), where Clerk satellite mode blocks normal email-code and OAuth sign-in.

Requires a [Platform API key](/coraltalk-apis/authentication). Call from your **server only** — never from the browser.

## Endpoints

| Method | Path                      | Description                                |
| ------ | ------------------------- | ------------------------------------------ |
| `POST` | `/students/sign-in-token` | Provision student and return sign-in token |

Full URL:

```
https://app.coraltalk.com/api/v1/{env}/students/sign-in-token
```

Use `prod` with `ct_live_` keys, or `dev` with `ct_test_` keys.

## Create sign-in token

| Field           | Required | Description                                         |
| --------------- | -------- | --------------------------------------------------- |
| `email`         | Yes      | Student email                                       |
| `firstName`     | Yes      | Given name                                          |
| `lastName`      | Yes      | Family name                                         |
| `orgInternalId` | Yes      | Your student identifier (roll number, SIS id, etc.) |
| `classId`       | Yes      | Class ID                                            |
| `courseId`      | No       | Course ID                                           |

```bash theme={null}
curl -X POST "https://app.coraltalk.com/api/v1/prod/students/sign-in-token" \
  -H "Authorization: Bearer ct_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "student@school.edu",
    "firstName": "Ada",
    "lastName": "Lovelace",
    "orgInternalId": "roll-12345",
    "classId": "CLASS_ID",
    "courseId": "COURSE_ID"
  }'
```

### Response

```json theme={null}
{
  "data": {
    "token": "signin_xxxxxxxx",
    "userId": "user_xxxxxxxx",
    "studentId": "674a1b2c3d4e5f6789012345",
    "created": true
  },
  "meta": {
    "requestId": "req_abc123"
  }
}
```

| Field       | Description                                                                                      |
| ----------- | ------------------------------------------------------------------------------------------------ |
| `token`     | Clerk sign-in token — use with `strategy: "ticket"` on the custom domain (expires in 10 minutes) |
| `userId`    | Clerk user ID                                                                                    |
| `studentId` | Coraltalk student enrollment ID                                                                  |
| `created`   | `true` if the student was newly enrolled in the class                                            |

## Behavior

* The class must belong to your organization and match the API key environment.
* If the student does not exist for that class, Coraltalk creates the Clerk user and enrollment.
* If the student already exists (matched by email or `orgInternalId` within the class), a new token is issued for the existing account.
* Class capacity limits apply; a full class returns `409` with code `conflict`.

Use `classId` from [Classes](/coraltalk-apis/classes). For exam links, the class is usually the exam’s `taAgent` field.

## Client usage

After your backend receives `data.token`, the exam page on the custom domain completes sign-in:

```typescript theme={null}
await signIn.create({ strategy: "ticket", ticket: token });
await signIn.finalize({ /* navigate to exam */ });
```

## Next steps

* [Authentication](/coraltalk-apis/authentication)
* [Custom domains](/coraltalk-apis/custom-domains)
* [Oral assessments](/coraltalk-apis/oral-assessments)
* [Roleplay](/coraltalk-apis/roleplay)
* [Errors](/coraltalk-apis/errors)
