jsonapi
Provides strict adherence to JSON:API v1.1 standards for API design and validation.
Install
mkdir -p .claude/skills/jsonapi && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/4037" && unzip -o skill.zip -d .claude/skills/jsonapi && rm skill.zipInstalls to .claude/skills/jsonapi
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Strict JSON:API v1.1 specification compliance. Trigger: When creating or modifying API endpoints, reviewing API responses, or validating JSON:API compliance.Key capabilities
- →Validate JSON:API spec v1.1 compliance
- →Ensure response structure conforms to mandatory data/errors/meta rules
- →Enforce string format for id and kebab-case for type
- →Verify media type compliance for headers
- →Check resource object constraints (id/type exclusions)
How it works
It validates input against the official JSON:API v1.1 specification document by checking for mandatory fields and structural restrictions.
Inputs & outputs
When to use jsonapi
- →Validate API endpoint structure against JSON:API spec
- →Ensure correct usage of resource type and id fields
- →Review API responses for specification compliance
About this skill
Use With django-drf
This skill focuses on spec compliance. For implementation patterns (ViewSets, Serializers, Filters), use django-drf skill together with this one.
| Skill | Focus |
|---|---|
jsonapi | What the spec requires (MUST/MUST NOT rules) |
django-drf | How to implement it in DRF (code patterns) |
When creating/modifying endpoints, invoke BOTH skills.
Before Implementing/Reviewing
ALWAYS validate against the latest spec before creating or modifying endpoints:
Option 1: Context7 MCP (Preferred)
If Context7 MCP is available, query the JSON:API spec directly:
mcp_context7_resolve-library-id(query="jsonapi specification")
mcp_context7_query-docs(libraryId="<resolved-id>", query="[specific topic: relationships, errors, etc.]")
Option 2: WebFetch (Fallback)
If Context7 is not available, fetch from the official spec:
WebFetch(url="https://jsonapi.org/format/", prompt="Extract rules for [specific topic]")
This ensures compliance with the latest JSON:API version, even after spec updates.
Critical Rules (NEVER Break)
Document Structure
- NEVER include both
dataanderrorsin the same response - ALWAYS include at least one of:
data,errors,meta - ALWAYS use
typeandid(string) in resource objects - NEVER include
idwhen creating resources (server generates it)
Content-Type
- ALWAYS use
Content-Type: application/vnd.api+json - ALWAYS use
Accept: application/vnd.api+json - NEVER add parameters to media type without
ext/profile
Resource Objects
- ALWAYS use string for
id(even if UUID) - ALWAYS use lowercase kebab-case for
type - NEVER put
idortypeinsideattributes - NEVER include foreign keys in
attributes- userelationships
Relationships
- ALWAYS include at least one of:
links,data, ormeta - ALWAYS use resource linkage format:
{"type": "...", "id": "..."} - NEVER use raw IDs in relationships - always use linkage objects
Error Objects
- ALWAYS return errors as array:
{"errors": [...]} - ALWAYS include
statusas string (e.g.,"400", not400) - ALWAYS include
source.pointerfor field-specific errors
HTTP Status Codes (Mandatory)
| Operation | Success | Async | Conflict | Not Found | Forbidden | Bad Request |
|---|---|---|---|---|---|---|
| GET | 200 | - | - | 404 | 403 | 400 |
| POST | 201 | 202 | 409 | 404 | 403 | 400 |
| PATCH | 200 | 202 | 409 | 404 | 403 | 400 |
| DELETE | 200/204 | 202 | - | 404 | 403 | - |
When to Use Each
| Code | Use When |
|---|---|
200 OK | Successful GET, PATCH with response body, DELETE with response |
201 Created | POST created resource (MUST include Location header) |
202 Accepted | Async operation started (return task reference) |
204 No Content | Successful DELETE, PATCH with no response body |
400 Bad Request | Invalid query params, malformed request, unknown fields |
403 Forbidden | Authentication ok but no permission, client-generated ID rejected |
404 Not Found | Resource doesn't exist OR RLS hides it (never reveal which) |
409 Conflict | Duplicate ID, type mismatch, relationship conflict |
415 Unsupported | Wrong Content-Type header |
Document Structure
Success Response (Single)
{
"data": {
"type": "providers",
"id": "550e8400-e29b-41d4-a716-446655440000",
"attributes": {
"alias": "Production",
"connected": true
},
"relationships": {
"tenant": {
"data": {"type": "tenants", "id": "..."}
}
},
"links": {
"self": "/api/v1/providers/550e8400-..."
}
},
"links": {
"self": "/api/v1/providers/550e8400-..."
}
}
Success Response (List)
{
"data": [
{"type": "providers", "id": "...", "attributes": {...}},
{"type": "providers", "id": "...", "attributes": {...}}
],
"links": {
"self": "/api/v1/providers?page[number]=1",
"first": "/api/v1/providers?page[number]=1",
"last": "/api/v1/providers?page[number]=5",
"prev": null,
"next": "/api/v1/providers?page[number]=2"
},
"meta": {
"pagination": {"count": 100, "pages": 5}
}
}
Error Response
{
"errors": [
{
"status": "400",
"code": "invalid",
"title": "Invalid attribute",
"detail": "UID must be 12 digits for AWS accounts",
"source": {"pointer": "/data/attributes/uid"}
}
]
}
Query Parameters
| Family | Format | Example |
|---|---|---|
page | page[number], page[size] | ?page[number]=2&page[size]=25 |
filter | filter[field], filter[field__op] | ?filter[status]=FAIL |
sort | Comma-separated, - for desc | ?sort=-inserted_at,name |
fields | fields[type] | ?fields[providers]=id,alias |
include | Comma-separated paths | ?include=provider,scan.task |
Rules
- MUST return
400for unsupported query parameters - MUST return
400for unsupportedincludepaths - MUST return
400for unsupportedsortfields - MUST NOT include extra fields when
fields[type]is specified
Common Violations (AVOID)
| Violation | Wrong | Correct |
|---|---|---|
| ID as integer | "id": 123 | "id": "123" |
| Type as camelCase | "type": "providerGroup" | "type": "provider-groups" |
| FK in attributes | "tenant_id": "..." | "relationships": {"tenant": {...}} |
| Errors not array | {"error": "..."} | {"errors": [{"detail": "..."}]} |
| Status as number | "status": 400 | "status": "400" |
| Data + errors | {"data": ..., "errors": ...} | Only one or the other |
| Missing pointer | {"detail": "Invalid"} | {"detail": "...", "source": {"pointer": "..."}} |
Relationship Updates
To-One Relationship
PATCH /api/v1/providers/123/relationships/tenant
Content-Type: application/vnd.api+json
{"data": {"type": "tenants", "id": "456"}}
To clear: {"data": null}
To-Many Relationship
| Operation | Method | Body |
|---|---|---|
| Replace all | PATCH | {"data": [{...}, {...}]} |
| Add members | POST | {"data": [{...}]} |
| Remove members | DELETE | {"data": [{...}]} |
Compound Documents (include)
When using ?include=provider:
{
"data": {
"type": "scans",
"id": "...",
"relationships": {
"provider": {
"data": {"type": "providers", "id": "prov-123"}
}
}
},
"included": [
{
"type": "providers",
"id": "prov-123",
"attributes": {"alias": "Production"}
}
]
}
Rules
- Every included resource MUST be reachable via relationship chain from primary data
- MUST NOT include orphan resources
- MUST NOT duplicate resources (same type+id)
Spec Reference
- Full Specification: https://jsonapi.org/format/
- Implementation: Use
django-drfskill for DRF-specific patterns - Testing: Use
prowler-test-apiskill for test patterns
When not to use it
- →APIs using non-JSON:API standards (e.g., standard REST, GraphQL)
- →Simple JSON payloads not needing strict specification compliance
Prerequisites
Limitations
- →Does not generate the backend logic itself
- →Requires external tools or web access to check the latest spec
How it compares
It enforces strict formal specification compliance rather than just checking if the code runs.
Compared to similar skills
jsonapi side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| jsonapi (this skill) | 1 | 2mo | No flags | Advanced |
| pagination | 1 | 6mo | No flags | Intermediate |
| moai-domain-backend | 1 | 3mo | Review | Advanced |
| senior-backend | 14 | 7mo | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by prowler-cloud
View all by prowler-cloud →You might also like
pagination
dadbodgeoff
Implement cursor-based and offset pagination for APIs. Covers efficient database queries, stable sorting, and pagination metadata.
moai-domain-backend
modu-ai
Backend development specialist covering API design, database integration, microservices architecture, and modern backend patterns.
senior-backend
davila7
Comprehensive backend development skill for building scalable backend systems using NodeJS, Express, Go, Python, Postgres, GraphQL, REST APIs. Includes API scaffolding, database optimization, security implementation, and performance tuning. Use when designing APIs, optimizing database queries, implementing business logic, handling authentication/authorization, or reviewing backend code.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
fastapi-pro
sickn33
Build high-performance async APIs with FastAPI, SQLAlchemy 2.0, and Pydantic V2. Master microservices, WebSockets, and modern Python async patterns. Use PROACTIVELY for FastAPI development, async optimization, or API architecture.
telegram-bot-builder
davila7
Expert in building Telegram bots that solve real problems - from simple automation to complex AI-powered bots. Covers bot architecture, the Telegram Bot API, user experience, monetization strategies, and scaling bots to thousands of users. Use when: telegram bot, bot api, telegram automation, chat bot telegram, tg bot.