Base URL: https://api.abchnexus.com/api
All endpoints (except /hello, /login, and /register) require authentication via Laravel Sanctum.
Include the token in the Authorization header:
Authorization: Bearer {your-token}
Also include these headers on every request:
Accept: application/json
Content-Type: application/json
Health check endpoint.
Response 200 OK
{
"message": "Hello World"
}POST /register
Create a new user account and receive an API token.
Request Body:
| Field | Type | Required | Rules |
|---|---|---|---|
name |
string | Yes | max 255 chars |
email |
string | Yes | valid email, unique, max 255 |
password |
string | Yes | min 8 chars (default rules) |
password_confirmation |
string | Yes | must match password |
Example Request:
{
"name": "John Doe",
"email": "john@example.com",
"password": "password123",
"password_confirmation": "password123"
}Response 201 Created
{
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"updated_at": "2026-03-04T10:00:00.000000Z",
"created_at": "2026-03-04T10:00:00.000000Z"
},
"token": "1|abc123def456..."
}Response 422 Unprocessable Entity (validation error)
{
"message": "The email has already been taken.",
"errors": {
"email": ["The email has already been taken."]
}
}POST /login
Authenticate and receive an API token.
Request Body:
| Field | Type | Required | Rules |
|---|---|---|---|
email |
string | Yes | valid email |
password |
string | Yes |
Example Request:
{
"email": "john@example.com",
"password": "password123"
}Response 200 OK
{
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"email_verified_at": "2026-03-04T10:00:00.000000Z",
"created_at": "2026-03-04T10:00:00.000000Z",
"updated_at": "2026-03-04T10:00:00.000000Z"
},
"token": "2|xyz789ghi012..."
}Response 422 Unprocessable Entity (invalid credentials)
{
"message": "The provided credentials are incorrect.",
"errors": {
"email": ["The provided credentials are incorrect."]
}
}POST /logout
Revoke the current API token. Requires authentication.
Headers: Authorization: Bearer {token}
Response 200 OK
{
"message": "Logged out successfully"
}Response 401 Unauthenticated — if token is missing or invalid.
GET /user
Returns the authenticated user's details.
Headers: Authorization: Bearer {token}
Response 200 OK
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"email_verified_at": "2026-03-04T10:00:00.000000Z",
"created_at": "2026-03-04T10:00:00.000000Z",
"updated_at": "2026-03-04T10:00:00.000000Z"
}All todo endpoints require authentication. Users can only access their own todos.
GET /todos
Returns all todos for the authenticated user, sorted by most recent first.
Response 200 OK
[
{
"id": 1,
"user_id": 1,
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"is_completed": false,
"created_at": "2026-03-04T12:00:00.000000Z",
"updated_at": "2026-03-04T12:00:00.000000Z"
},
{
"id": 2,
"user_id": 1,
"title": "Walk the dog",
"description": null,
"is_completed": true,
"created_at": "2026-03-04T11:00:00.000000Z",
"updated_at": "2026-03-04T11:30:00.000000Z"
}
]POST /todos
Request Body:
| Field | Type | Required | Rules |
|---|---|---|---|
title |
string | Yes | max 255 chars |
description |
string | No | max 1000 chars |
Example Request:
{
"title": "Buy groceries",
"description": "Milk, eggs, bread"
}Response 201 Created
{
"id": 3,
"user_id": 1,
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"is_completed": false,
"created_at": "2026-03-04T14:00:00.000000Z",
"updated_at": "2026-03-04T14:00:00.000000Z"
}Response 422 Unprocessable Entity (validation error)
{
"message": "The title field is required.",
"errors": {
"title": ["The title field is required."]
}
}GET /todos/{id}
Returns a single todo by ID.
Response 200 OK
{
"id": 1,
"user_id": 1,
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"is_completed": false,
"created_at": "2026-03-04T12:00:00.000000Z",
"updated_at": "2026-03-04T12:00:00.000000Z"
}Response 403 Forbidden — if the todo belongs to another user.
Response 404 Not Found — if the todo doesn't exist.
PUT /todos/{id} or PATCH /todos/{id}
All fields are optional — send only what you want to change.
Request Body:
| Field | Type | Required | Rules |
|---|---|---|---|
title |
string | No | max 255 chars |
description |
string | No | max 1000 chars |
is_completed |
boolean | No | true or false |
Example — Mark as completed:
{
"is_completed": true
}Example — Update title and description:
{
"title": "Buy more groceries",
"description": "Milk, eggs, bread, butter"
}Response 200 OK
{
"id": 1,
"user_id": 1,
"title": "Buy more groceries",
"description": "Milk, eggs, bread, butter",
"is_completed": true,
"created_at": "2026-03-04T12:00:00.000000Z",
"updated_at": "2026-03-04T15:00:00.000000Z"
}Response 403 Forbidden — if the todo belongs to another user.
Response 404 Not Found — if the todo doesn't exist.
DELETE /todos/{id}
Response 200 OK
{
"message": "Todo deleted"
}Response 403 Forbidden — if the todo belongs to another user.
Response 404 Not Found — if the todo doesn't exist.
| Field | Type | Description |
|---|---|---|
id |
integer | Unique identifier |
user_id |
integer | Owner's user ID |
title |
string | Todo title (max 255 chars) |
description |
string? | Optional details (max 1000 chars) |
is_completed |
boolean | Completion status |
created_at |
datetime | ISO 8601 timestamp |
updated_at |
datetime | ISO 8601 timestamp |
| Status | Meaning |
|---|---|
401 |
Unauthenticated — missing or invalid token |
403 |
Forbidden — accessing another user's todo |
404 |
Not Found — todo doesn't exist |
422 |
Validation Error — invalid request body |
500 |
Server Error |