Joomla Web Services API — REST API and Application Endpoints
In this tutorial, you'll learn how to use the Joomla Web Services API — enabling the built-in REST API, authenticating with tokens, making GET and POST requests to core endpoints (articles, categories, users), and creating custom API plugins.
What You'll Learn
- What the Joomla REST API is and how it works
- Creating an API Super User and generating authentication tokens
- Making GET requests to fetch articles, categories, and users
- Making POST requests to create new content via the API
- Understanding the JSON response format
- Creating custom API plugins for custom endpoints
- API security considerations and Rate Limiting
Why It Matters
The Joomla REST API, introduced in Joomla 4, turns your site into a headless CMS. External applications — mobile apps, single-page applications, third-party services — can read and write content programmatically. You can build a React or Vue frontend that pulls content from Joomla via the API. You can automate content creation from external tools. You can integrate Joomla with other systems (CRMs, marketing platforms, dashboards) without writing custom PHP extensions. The API is built on standard REST principles and uses JSON, making it accessible to any developer familiar with web APIs.
Real-World Use
A media company runs its main website on Joomla but wants to display the latest articles on a React-based mobile app. Rather than building a separate content backend, the mobile app calls /api/index.php/v1/articles every 15 minutes to fetch the latest published articles. The API returns JSON with article titles, intro text, images, and publish dates. The same API is used by the company's digital signage system in the office lobby. Both integrations were built in days using the core Joomla REST API, no extensions needed.
Learning Path
flowchart LR A["Custom Fields"] --> B["Joomla API"] B --> C["Database Maintenance"] C --> D["Go-Live Checklist"] classDef current fill:#38bdf8,color:#0f172a,stroke-width:2px class B current
What is the Joomla API?
Joomla's REST API is a built-in web service that allows external applications to interact with your Joomla site over HTTP. It was introduced in Joomla 4 as part of the API Application.
The API is implemented as a separate Joomla application, accessible at /api/index.php. It uses token-based authentication and returns JSON.
API Application Architecture
flowchart LR A["Client App"] --> B["HTTP Request"] B --> C["api/index.php"] C --> D["Authenticate"] D --> E["Route to Endpoint"] E --> F["JSON Response"] F --> A style C fill:#38bdf8,color:#0f172a style D fill:#38bdf8,color:#0f172a style E fill:#38bdf8,color:#0f172a
Enabling the API
Step 1: Create an API Super User
The API does not use the regular Joomla login. It requires a dedicated API Super User with a unique token.
Go to Users > Users
Click New
Create a user with:
- Name: API User
- Username: apiuser
- Email: api@example.com
- Password: (generate a strong password)
- Group: Super Users
In the API Token tab:
- Click Generate to create a token
- Copy the token — you will not be able to see it again
Step 2: Enable the API Application
- Go to System > Global Configuration > API
- Set Enable API to Yes
- Configure CORS settings if needed:
| Setting | Value |
|---|---|
| Access-Control-Allow-Origin | * (or specific domains) |
| Access-Control-Allow-Headers | Authorization, Content-Type |
Step 3: Test the API
# Test connection — should return JSON list of available endpoints
curl https://yoursite.com/api/index.php/v1
API Endpoint Structure
The API follows RESTful conventions:
Base URL: https://yoursite.com/api/index.php/v1
GET /v1/articles → List articles
GET /v1/articles/:id → Get single article
POST /v1/articles → Create article
PATCH /v1/articles/:id → Update article
DELETE /v1/articles/:id → Delete article
Available Core Endpoints
| Endpoint | Description |
|---|---|
GET /v1/articles |
List articles |
GET /v1/articles/:id |
Get single article |
POST /v1/articles |
Create article |
PATCH /v1/articles/:id |
Update article |
DELETE /v1/articles/:id |
Delete article |
GET /v1/categories |
List categories |
GET /v1/users |
List users |
GET /v1/users/:id |
Get single user |
POST /v1/users |
Create user |
GET /v1/contacts |
List contacts |
GET /v1/config |
Get site configuration |
GET /v1/languages |
List languages |
GET /v1/tags |
List tags |
GET /v1/media |
List media files |
GET /v1/modules |
List modules |
GET /v1/plugins |
List plugins |
GET /v1/templates |
List templates |
GET /v1/banners |
List banners |
GET /v1/fields |
List custom fields |
Authentication Methods
Joomla API uses Bearer Token authentication.
Token Authentication
# Include the token in the Authorization header
curl -H "Authorization: Bearer YOUR_TOKEN_HERE" \
https://yoursite.com/api/index.php/v1/articles
Token Management
Each API Super User has one token. To regenerate:
- Edit the API user in Users > Users
- Go to the API Token tab
- Click Regenerate
- Copy the new token
Important: Store tokens securely. Anyone with the token has full access as that user.
Making GET Requests
Fetch Articles
curl -H "Authorization: Bearer YOUR_TOKEN" \
"https://yoursite.com/api/index.php/v1/articles"
Response:
{
"data": [
{
"id": "42",
"type": "articles",
"attributes": {
"title": "Hello World",
"alias": "hello-world",
"introtext": "<p>Welcome to my first article.</p>",
"fulltext": "",
"state": 1,
"catid": 9,
"created": "2026-06-27 10:00:00",
"created_by": 42,
"modified": "2026-06-27 10:30:00",
"publish_up": "2026-06-27 10:00:00",
"access": 1
},
"links": {
"self": "https://yoursite.com/api/index.php/v1/articles/42"
}
}
],
"links": {
"self": "https://yoursite.com/api/index.php/v1/articles",
"first": "https://yoursite.com/api/index.php/v1/articles",
"next": "https://yoursite.com/api/index.php/v1/articles?offset=20"
},
"meta": {
"total": 150,
"offset": 0,
"limit": 20
}
}
Fetch Single Article
curl -H "Authorization: Bearer YOUR_TOKEN" \
"https://yoursite.com/api/index.php/v1/articles/42"
Query Parameters
| Parameter | Description | Example |
|---|---|---|
search |
Search term | ?search=hello |
filter[category_id] |
Filter by category | ?filter[category_id]=9 |
filter[author] |
Filter by author ID | ?filter[author]=42 |
sort |
Sort field | ?sort=-created (descending) |
offset |
Pagination offset | ?offset=20 |
limit |
Items per page | ?limit=100 |
Making POST Requests
Create an Article
curl -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "API Created Article",
"alias": "api-created-article",
"introtext": "<p>This article was created via the Joomla REST API.</p>",
"catid": 9,
"language": "*",
"access": 1,
"state": 1
}' \
"https://yoursite.com/api/index.php/v1/articles"
Response:
{
"data": {
"id": "43",
"type": "articles",
"attributes": {
"title": "API Created Article",
"alias": "api-created-article",
"introtext": "<p>This article was created via the Joomla REST API.</p>",
"state": 1,
"catid": 9
}
}
}
Create a Category
curl -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "API Category",
"alias": "api-category",
"parent_id": 1,
"published": 1,
"language": "*"
}' \
"https://yoursite.com/api/index.php/v1/categories"
Making PATCH Requests
Update an Article
curl -X PATCH \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"introtext": "<p>Updated content via API.</p>",
"state": 0
}' \
"https://yoursite.com/api/index.php/v1/articles/43"
Making DELETE Requests
curl -X DELETE \
-H "Authorization: Bearer YOUR_TOKEN" \
"https://yoursite.com/api/index.php/v1/articles/43"
API Response Format
All API responses follow JSON:API specification:
{
"data": { ... }, // Single item or array of items
"links": { ... }, // Pagination and self links
"meta": { ... }, // Metadata (total, offset, limit)
"included": [ ... ] // Optional related resources
}
Error Responses
{
"errors": [
{
"title": "Article not found",
"status": "404",
"detail": "The requested article with ID 999 does not exist."
}
]
}
Creating a Custom API Plugin
You can extend the API with custom endpoints by creating a plugin.
Plugin Structure
<?php
// src/plugins/api-authentication/myapi/myapi.php
defined('_JEXEC') or die;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Router\ApiRouter;
use Joomla\CMS\Factory;
class PlgApiAuthenticationMyApi extends CMSPlugin
{
protected $autoloadLanguage = true;
public function onBeforeApiRoute(&$router)
{
$router->createCRUDRoutes(
'v1/myitems',
'myitems',
['component' => 'com_myapi']
);
}
}
Registering Routes
// In your plugin's onBeforeApiRoute method
public function onBeforeApiRoute(&$router)
{
// Custom GET route
$router->get(
'v1/custom/data',
'CustomController.getData',
['component' => 'com_customapi']
);
// Custom POST route
$router->post(
'v1/custom/data',
'CustomController.createData',
['component' => 'com_customapi']
);
}
API Rate Limiting
Joomla does not include built-in rate limiting for the API. For production use, implement rate limiting at the web server level:
# Apache rate limiting (requires mod_ratelimit)
<IfModule mod_ratelimit.c>
<Location "/api/">
SetOutputFilter RATE_LIMIT
SetEnv rate-limit 50
</Location>
</IfModule>
API Security
- Use HTTPS — never send API tokens over unencrypted HTTP
- Rotate tokens periodically — generate new tokens every 90 days
- Use Super Users only — only Super Users can authenticate via API
- Restrict CORS — set specific origins instead of wildcard in production
- Log API requests — enable Joomla's logging to monitor API usage
Common Mistakes
Sending the token in the URL instead of the header: Tokens in URLs get logged in server access logs and browser history. Always use the Authorization header:
Authorization: Bearer YOUR_TOKEN.Not setting CORS headers for frontend apps: If your JavaScript app runs on a different domain, the browser blocks the API request. Configure CORS in Global Configuration > API with the correct origin domains.
Forgetting Content-Type header for POST/PATCH: The API needs
Content-Type: application/jsonto parse the request body. Without it, the API returns an empty body error.Using the wrong HTTP method: Use GET for reading, POST for creating, PATCH for partial updates, DELETE for removing. Using GET to create content returns an error.
Not paginating large result sets: Fetching all 10,000 articles without pagination can timeout. Use limit and offset parameters:
?limit=50&offset=0.
Practice Questions
What authentication method does the Joomla API use? Answer: Bearer Token authentication. Create an API Super User in Users > Users, generate a token, and include it in the Authorization header of every request:
Authorization: Bearer YOUR_TOKEN.How do you create a new article via the Joomla API? Answer: Send a POST request to
/api/index.php/v1/articleswith a JSON body containing title, introtext, catid, and other fields. Include theContent-Type: application/jsonheader and the Bearer authorization token.What is the JSON:API response format, and what sections does it contain? Answer: The JSON:API response contains three main sections:
data(the actual content),links(pagination and self-referencing URLs), andmeta(total count, offset, limit). Errors return anerrorsarray.Challenge: Build a simple integration between Joomla and an external application. Write a Python script that: authenticates with the Joomla API, fetches the latest 10 articles, creates a new article with content from a local file, updates the article's title, and deletes the article. Then build a simple PHP plugin that adds a custom API endpoint returning custom data.
FAQ
Mini Project
Your task is to build a headless Joomla integration.
- Set up a Joomla 5 site with at least 20 articles across 5 categories
- Create an API Super User and generate a token
- Using curl or a programming language of your choice:
- Fetch all articles and print their titles
- Fetch articles filtered by a specific category
- Create a new article with a title and content from a text file
- Update the article's title
- Fetch the single article to confirm the update
- Delete the article
- Build a simple custom API plugin that adds a
/v1/healthendpoint returning server status - Document all API calls with the curl commands used and the responses received
What's Next
Now that you understand the API, learn about database maintenance:
Continue to Lesson 39: Joomla Database Maintenance — Database tools, cache clearing, and system optimization.
Related lessons:
- {{< ilink "Joomla" "Joomla Custom Fields" }} — API for custom field data
- {{< ilink "Joomla" "Joomla Go-Live Checklist" }} — Production API configuration
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro