Skip to main content

Quickstart — first API call

The local stack will be defined in docker-compose.yml once /scaffold-service lands the runtime config. Until then, this page describes the contract you'll exercise.

1. Get a token

curl -X POST http://localhost:8080/api/v1/auth/login \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: 01J9Z9F3KX5N2RQ4P7M8YQK6T2' \
-H 'X-Tenant-Id: ten_01J9Z9F3KX5N2RQ4P7M8YQK6T2' \
-d '{ "email": "learner@example.test", "password": "<masked>" }'

The response carries { data: { accessToken, refreshToken }, meta }.

2. Call a tenant-scoped endpoint

curl -X GET https://api.ghasi.io/api/v1/courses?cursor=eyJ2IjoxfQ \
-H 'Authorization: Bearer <jwt>' \
-H 'X-Tenant-Id: ten_01J…' \
-H 'Accept-Language: en'

3. Inspect the envelope

Success envelope
{
"data": {
"id": "crs_01J9Z9F3KX5N2RQ4P7M8YQK6T2",
"title": "Intro to Algebra",
"tenantId": "ten_01J9Z9F3KX5N2RQ4P7M8YQK6T2",
"createdAt": "2026-04-17T09:42:11.000Z"
},
"meta": {
"requestId": "req_01J9Z9F3KX5N2RQ4P7M8YQK6T2",
"apiVersion": "v1.0",
"traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
"page": {
"size": 50,
"cursor": null,
"nextCursor": "eyJ2IjoxLCJrIjp7fX0"
}
}
}

4. Trigger an error to see the problem+json shape

RFC 9457 problem+json
{
"error": {
"type": "https://errors.ghasi.io/validation/field_required",
"code": "validation.field_required",
"title": "Missing required field",
"status": 422,
"detail": "Field 'email' is required.",
"instance": "/api/v1/users",
"errors": [
{
"field": "email",
"code": "required"
}
],
"traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
"requestId": "req_01J9Z9F3KX5N2RQ4P7M8YQK6T2",
"retriable": false,
"retryAfter": null,
"docUrl": "https://docs.ghasi.io/errors/validation/field_required"
}
}