HomeDocumentation

Documentation

Everything you need to integrate TrafficNinja into your stack — REST API reference and WordPress plugin guide.

REST API

API Integration

The TrafficNinja REST API lets you programmatically manage websites, categories, themes, and sync generated articles to your platform. All endpoints are prefixed with /api/v1/.

Base URL

https://trafficninja.io/api/v1

Authentication

TrafficNinja uses Bearer token authentication via Laravel Sanctum. Obtain a token by logging in, then include it in every protected request.

1. Register

http
POST /api/v1/auth/register
Content-Type: application/json

{
  "name": "Acme Corp",
  "email": "hello@acme.com",
  "password": "secret",
  "password_confirmation": "secret"
}

2. Login

http
POST /api/v1/auth/login
Content-Type: application/json

{
  "email": "hello@acme.com",
  "password": "secret"
}
json
{
  "token": "1|abc123...",
  "user": { "id": 1, "name": "Acme Corp", "email": "hello@acme.com" }
}

3. Use the token

bash
curl https://trafficninja.io/api/v1/websites \
  -H "Authorization: Bearer 1|abc123..." \
  -H "Accept: application/json"

Core Endpoints

Websites

GET/api/v1/websitesList all websites Auth
POST/api/v1/websitesCreate a website Auth
GET/api/v1/websites/{id}Get a website Auth
PUT/api/v1/websites/{id}Update a website Auth
DELETE/api/v1/websites/{id}Delete a website Auth
GET/api/v1/websites/{id}/wordpress-api-keyGet WP API key Auth
POST/api/v1/websites/{id}/wordpress-api-key/generateRegenerate WP API key Auth

Categories

GET/api/v1/websites/{id}/categoriesList categories Auth
POST/api/v1/websites/{id}/categoriesCreate category Auth
PUT/api/v1/categories/{id}Update category Auth
DELETE/api/v1/categories/{id}Delete category Auth
POST/api/v1/websites/{id}/categories/generateAI-generate categories Auth

Themes & Posts

GET/api/v1/categories/{id}/themesList themes Auth
POST/api/v1/categories/{id}/themes/generateAI-generate themes Auth
GET/api/v1/postsList posts Auth
GET/api/v1/posts/{id}Get post Auth

User & Subscription

GET/api/v1/meGet current user Auth
PUT/api/v1/user/profileUpdate profile Auth
PUT/api/v1/user/passwordChange password Auth
GET/api/v1/subscriptionGet subscription Auth

Languages

GET/api/v1/languagesList supported languages Auth
GET/api/v1/websites/{id}/languagesGet website language config Auth
PUT/api/v1/websites/{id}/languagesUpdate website languages Auth

Example: Create a website

http
POST /api/v1/websites
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "My Blog",
  "url": "https://myblog.com",
  "industry": "technology",
  "country": "US",
  "language": "en"
}
json
{
  "id": 42,
  "name": "My Blog",
  "url": "https://myblog.com",
  "status": "active",
  "created_at": "2026-04-10T12:00:00Z"
}

WordPress Plugin Endpoints

These endpoints are consumed by the WordPress plugin using a per-site WordPress API Key (generated in the dashboard). Pass it as a header:

http
X-WordPress-Api-Key: {your-wordpress-api-key}
GET/api/wordpress/connection-testVerify API key + connectivity
GET/api/wordpress/content-queueFetch articles ready to publish
GET/api/wordpress/content/{id}Get full article content
GET/api/wordpress/language-configGet multi-language settings
GET/api/wordpress/categoriesGet mapped WP categories

Content queue item shape

json
{
  "id": 99,
  "title": "10 Ways to Boost Local SEO",
  "slug": "10-ways-boost-local-seo",
  "content": "<h2>...</h2><p>...</p>",
  "meta_description": "Learn how to dominate local search...",
  "focus_keyword": "local SEO tips",
  "json_ld": "{"@context":"https://schema.org",...}",
  "locale": "en",
  "categories": ["SEO", "Marketing"],
  "scheduled_for": "2026-04-11T08:00:00Z"
}

Error Handling

All errors return JSON with a consistent shape:

json
{
  "message": "The given data was invalid.",
  "errors": {
    "email": ["The email field is required."]
  }
}
400Bad Request — validation failed
401Unauthorized — missing or invalid token
403Forbidden — insufficient permissions
404Not Found — resource does not exist
422Unprocessable Entity — business logic error
429Too Many Requests — rate limited
500Server Error — try again later