API Key
Base URL: https://api-sls.platzi.com/production-sls-business-domains
Endpoints under /v2/api-key/auth/ let you validate an API key and generate single-use SSO magic links for users that already exist in your company.
Both endpoints self-authenticate via the x-platzi-company-api-key header
GET /v2/api-key/auth/validation/ - Validate API Key
Validates the API key provided in the x-platzi-company-api-key header and returns the claims associated with it.
Use this endpoint to verify that a key is active and to read the company_id, organization_id, role, and granted scope before calling other endpoints.
Request
GET /v2/api-key/auth/validation/
x-platzi-company-api-key: platzi-xxxxxxxxxxxx.xxxxxxxx...
User-Agent: <your-user-agent>
Success Response (200)
{
"data": {
"company_id": "123",
"organization_id": "10",
"user_id": "4567",
"user_profile_id": "8910",
"user_role": "company_admin",
"scope": "reports.read,sso.magiclink"
}
}
Response Fields
| Field | Description |
|---|---|
company_id | Company the key belongs to |
organization_id | Organization associated with the key |
user_id | User ID tied to the key |
user_profile_id | User profile ID tied to the key |
user_role | Role granted to the key |
scope | Comma-separated list of scopes granted to the key |
Error Response (401)
{
"errors": [
{ "error_code": "unauthorized_user", "message": "Unauthorized user" }
]
}
Returned when the header is missing, malformed, or the key has expired.
GET /v2/api-key/auth/magic-link/ - Generate SSO Magic Link
Generates a single-use magic link that logs a B2B user into Platzi without a password. Requires the API key to have the sso.magiclink scope.
The user identifier (email, username, or phone number) must be encrypted with the api_secret tied to your API key, using Fernet symmetric encryption. The api_secret is provided by Platzi organizers when the key is issued.
Request
GET /v2/api-key/auth/magic-link/?email=<encrypted-value>&only_active=true&next_url=/browse
x-platzi-company-api-key: platzi-xxxxxxxxxxxx.xxxxxxxx...
User-Agent: <your-user-agent>
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | one-of | Fernet-encrypted email. Exactly one identifier must be provided. |
username | string | one-of | Fernet-encrypted username. Only accepted when the company setting allows. |
phone_number | string | one-of | Fernet-encrypted phone number. Only accepted when the company setting allows. |
only_active | string | no | true/false (default false). If true, reject users that are not active. |
next_url | string | no | Relative path to redirect to after login (e.g. /browse). |
Identifier Rules
- Exactly one of
email,username, orphone_numbermust be supplied. Providing zero or more than one returns400. usernameandphone_numberare only accepted when the company has that setting enabled. Ask Platzi organizers if you need it.- The identifier value must be encrypted with your
api_secret(Fernet) before being sent as a query parameter.
Active User Rule (only_active=true)
When only_active=true, the user is accepted only if they are currently active in the company — i.e. fully active, or still in the invitation phase with at least one reserved/active license. Otherwise the request fails with user_not_active.
Success Response (200)
{
"data": {
"url": "https://platzi.com/sso/magic-link/verify/?token=abc123..."
}
}
The returned url is single-use and short-lived. Redirect the end user to it to complete the SSO flow.
Error Response
{
"errors": [
{
"error_code": "user_not_found",
"message": "User not found in company"
}
]
}
Error Codes
| Code | Status | Description |
|---|---|---|
missing_api_key | 401 | x-platzi-company-api-key header is missing |
invalid_api_key | 401 | API key is invalid or expired |
unauthorized_scope | 401 | API key does not include the sso.magiclink scope |
invalid_identifier | 400 | Zero or more than one identifier was provided |
identifier_not_allowed | 400 | Company does not allow username / phone_number identifiers |
decryption_failed | 400 | Identifier could not be decrypted with the key's api_secret |
user_not_found | 400 | Identifier does not match a user in the company |
user_not_active | 400 | only_active=true was set and the user is not active in the company |
magic_link_generation_failed | 500 | Internal error while generating the magic link |
GET /v2/api-key/auth/magic-link/course/ - Magic Link with Course Classes
Generates one SSO magic-link token and returns it alongside the
classes inside a given course. Every class entry carries its own deep
link, built from the single token plus a next= query parameter that
points to that specific class.
Requires the API key to have the sso.magiclink scope.
Request
GET /v2/api-key/auth/magic-link/course/?email=<encrypted-value>&course_id=1234
x-platzi-company-api-key: platzi-xxxxxxxxxxxx.xxxxxxxx...
User-Agent: <your-user-agent>
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | one-of | Fernet-encrypted email. Exactly one identifier must be provided. |
username | string | one-of | Fernet-encrypted username. Only accepted when the company setting allows. |
phone_number | string | one-of | Fernet-encrypted phone number. Only accepted when the company setting allows. |
course_id | integer | yes | Numeric Core course ID. Must be a positive integer. |
Identifier and encryption rules are identical to
/v2/api-key/auth/magic-link/.
Success Response (200)
{
"data": {
"magic_link_base": "https://platzi.com/sso/magic-link/verify/?token=abc123...",
"course_id": 1234,
"classes": [
{
"material_id": 88,
"name": "Introducción",
"viewed": false,
"magic_link": "https://platzi.com/sso/magic-link/verify/?token=abc123...&next=%2Fcursos%2Freact%2Fintroduccion%2F"
}
]
}
}
Response Fields
| Field | Description |
|---|---|
magic_link_base | The single magic-link URL (no class-specific next). One-time use. |
course_id | Echoed back from the request. |
classes | Array of classes (materials) inside the course, in pedagogic order. |
material_id | Numeric class (material) ID. |
name | Class name as it appears in Platzi. |
viewed | Whether the user has viewed this class. |
magic_link | Single-use SSO URL that lands the user on this class after login. |
Notes
- The shared
magic_link_baseand every per-classmagic_linkredeem the same one-time token; thenextquery parameter is the only difference. Once the token is consumed all class links stop working. viewedreflects per-material viewed state.- This endpoint does not verify that the user has access to the course (license / catalog / private course rules). Validate access upstream if your flow requires it.
- An existing course with no published classes returns
200withclasses: [].
Error Codes
| Code | Status | Description |
|---|---|---|
missing_api_key | 401 | x-platzi-company-api-key header is missing |
invalid_api_key | 401 | API key is invalid or expired |
unauthorized_scope | 401 | API key does not include the sso.magiclink scope |
invalid_identifier | 400 | Zero or more than one identifier was provided |
invalid_course_id | 400 | course_id is missing, non-numeric, or non-positive |
identifier_not_allowed | 400 | Company does not allow username / phone_number identifiers |
decryption_failed | 400 | Identifier could not be decrypted with the key's api_secret |
user_not_found | 400 | Identifier does not match a user in the company |
course_not_found | 404 | course_id does not match any existing course |
magic_link_generation_failed | 500 | Internal error while generating the magic link |