Skip to main content

🔐 API Permissions

Webtools exposes API endpoints that your frontend application uses to fetch content by URL path. This requires proper permissions configuration.

❗️ Required for Frontend

Without the proper permissions, you'll get a 403 Forbidden error when calling:

  • GET /api/webtools/router?path=...
  • GET /api/webtools/url-alias

1. Content-Type Permissions​

For each content-type where you've enabled Webtools, you need to enable the find permission.

Configuration Steps​

  1. Go to Strapi Admin → Settings → Users & Permissions plugin → Roles
  2. Select the role (e.g., Public or Authenticated)
  3. Under Application you'll find your enabled content-types (e.g., page, article)
  4. Check Find (and Find One if desired)
  5. Click Save
Content Type Find permissionsContent Type Find permissions

What it enables​

  • Allows the router endpoint to return content data for your content-types
  • Required for fetching content by URL path via /api/webtools/router

2. Webtools Plugin Permissions​

Enable the Webtools API endpoints for your frontend application.

Configuration Steps​

  1. In the same role (e.g., Public) scroll to the Webtools section
  2. Check:
    • Router: find
    • URL Alias: find
  3. Click Save
Webtools Router & URL Alias find permissionsWebtools Router & URL Alias find permissions

What it enables​

PermissionEndpointDescription
Router: findGET /api/webtools/router?path=...Allows to fetch content by URL path for routing in frontend applications
URL Alias: findGET /api/webtools/url-aliasAllows to fetch all URL aliases for generating static routes

Access via API Tokens​

In addition to the Users & Permissions plugin (for public and authenticated users), you can use API Tokens for programmatic access to Webtools endpoints.

When to use API Tokens​

  • Build-time data fetching: Static site generators (Next.js, Gatsby, etc.)
  • Server-to-server communication: Backend services fetching content by URL
  • CI/CD pipelines: Automated testing or validation
  • Development tools: Local development scripts fetching routes

Creating an API Token​

  1. Go to Strapi Admin → Settings → API Tokens

  2. Click Create new API Token

  3. Configure the token:

    • Name: e.g., "Frontend Build Token" or "Webtools API Access"
    • Description: Optional description of the token's purpose
    • Token duration: Unlimited, 7 days, 30 days, or 90 days
    • Token type: Choose based on your needs:
      • Read-only: Can only fetch data (recommended for webtools)
      • Full access: Can create, update, and delete (use with caution)
      • Custom: Fine-grained permissions (see below)
  4. Click Save and copy the generated token immediately (it won't be shown again)

Configuring Custom Permissions for API Tokens​

For better security, use Custom token type with specific permissions:

  1. Select Custom as Token type
  2. Enable permissions for your content-types:
    • Under each content-type: find and findOne
  3. Scroll to Webtools section
  4. Enable:
    • Router: find
    • URL Alias: find
💡 Security Best Practice

Use Read-only tokens or Custom tokens with only find permissions enabled for frontend applications. Never expose tokens with write permissions in client-side code.

Using the API Token​

Include the token in the Authorization header when making requests:

# Fetch content by URL path
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
"http://localhost:1337/api/webtools/router?path=/about-us"

# Fetch all URL aliases
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
"http://localhost:1337/api/webtools/url-alias"

Next.js example (server-side):

// app/[...slug]/page.tsx
export async function generateStaticParams() {
const response = await fetch('https://your-strapi.com/api/webtools/url-alias', {
headers: {
'Authorization': `Bearer ${process.env.STRAPI_API_TOKEN}`,
},
});
const aliases = await response.json();

return aliases.data.map((alias) => ({
slug: alias.attributes.url_path.split('/').filter(Boolean),
}));
}

export default async function Page({ params }) {
const path = '/' + params.slug.join('/');

const response = await fetch(
`https://your-strapi.com/api/webtools/router?path=${path}`,
{
headers: {
'Authorization': `Bearer ${process.env.STRAPI_API_TOKEN}`,
},
}
);

const data = await response.json();
// Render your page...
}

Important: Store API tokens in environment variables (.env.local), never commit them to version control.


Testing API Access​

Test with Public/Authenticated role​

# Without authentication (requires Public role permissions)
curl "http://localhost:1337/api/webtools/router?path=/about-us"

# With user JWT token (requires Authenticated role permissions)
curl -H "Authorization: Bearer USER_JWT_TOKEN" \
"http://localhost:1337/api/webtools/router?path=/about-us"

Test with API Token​

curl -H "Authorization: Bearer YOUR_API_TOKEN" \
"http://localhost:1337/api/webtools/router?path=/about-us"

Expected response:

{
"data": {
"id": 1,
"documentId": "abc123",
"title": "About Us",
"content": "...",
// ... other content fields
},
"meta": {
"contentType": "api::page.page"
}
}
💡 Tip

Restart Strapi after making permission changes and clear your browser cache if needed.


Troubleshooting​

403 Forbidden Error:

  • Verify the correct role (Public/Authenticated) has permissions enabled for:
    • Content-type find permission
    • Webtools Router: find permission
    • Webtools URL Alias: find permission (if using that endpoint)
  • If using API token, verify it's valid and has correct permissions
  • Restart Strapi after permission changes
  • Check that the token hasn't expired

API Token not working:

  • Ensure token is included in Authorization: Bearer TOKEN header
  • Verify token hasn't expired
  • Check token type has necessary permissions (not Read-only for write operations)
  • Regenerate token if needed

Content returns empty:

  • Verify content is published (not draft)
  • Check that URL alias exists for the content
  • Ensure content-type has Webtools enabled in schema
  • Verify content has a valid url_alias relation

CORS issues in frontend:

  • Configure CORS in config/middlewares.js:
module.exports = [
// ...
{
name: 'strapi::cors',
config: {
origin: ['http://localhost:3000', 'https://your-frontend.com'],
},
},
];