design-api — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited design-api (Agent Skill) and scored it 45/100 (orange). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 1 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
A base64 string of 128+ characters appears in a documentation file. Encoded prompt injection hides the hostile instruction in base64 — invisible to keyword filters — and relies on the agent's ability to decode it at runtime. There is no normal authoring reason to embed a multi-hundred-byte base64 blob in skill docs.
*.sig, SIGNATURES) outside the documentation.Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Design clean, consistent, and developer-friendly APIs.
BEFORE designing any API, you MUST:
http://localhost:8080/api-docs (if backend running)
http://localhost:8080/naming-conventions (naming standards)
src/api/_api-README.md (frontend API layer docs)Use Supabase MCP to understand existing data structure:
-- Check table schema
SELECT column_name, data_type, is_nullable
FROM information_schema.columns WHERE table_name = 'your_table';
-- Check enum values
SELECT enum_range(NULL::your_enum_name);
-- Check foreign keys
SELECT tc.constraint_name, kcu.column_name, ccu.table_name AS foreign_table
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage ccu ON tc.constraint_name = ccu.constraint_name
WHERE tc.table_name = 'your_table' AND tc.constraint_type = 'FOREIGN KEY';Use Grep to search for similar endpoints already implemented:
Grep: "router.get|router.post" to find existing route patterns
Grep: "useQuery|useMutation" to find existing frontend integrationsBefore designing, state:
"Pre-design check:
- Existing API docs reviewed: [YES/NO]
- Database schema verified: [tables/enums checked]
- Similar endpoints found: [list or none]
- Naming conventions confirmed: [YES/NO]"GET /resources # List
GET /resources/:id # Get one
POST /resources # Create
PUT /resources/:id # Replace
PATCH /resources/:id # Update
DELETE /resources/:id # Delete| Do | Don't |
|---|---|
/users | /getUsers, /user-list |
/users/:id | /user/:id, /users/get/:id |
/users/:id/orders | /getUserOrders |
| Plural nouns | Verbs, singular |
| kebab-case | camelCase, snake_case |
GET /users # List users
GET /users/123 # Get user 123
GET /users/123/orders # User's orders
GET /users/123/orders/456 # Specific order
POST /users/123/orders # Create order for user{
"name": "John Doe",
"email": "[email protected]",
"role": "admin"
}{
"data": {
"id": "123",
"name": "John Doe",
"email": "[email protected]",
"createdAt": "2024-01-15T10:30:00Z"
}
}{
"data": [
{ "id": "1", "name": "John" },
{ "id": "2", "name": "Jane" }
],
"meta": {
"total": 100,
"page": 1,
"perPage": 20,
"totalPages": 5
}
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input data",
"details": [
{ "field": "email", "message": "Invalid email format" },
{ "field": "name", "message": "Name is required" }
]
}
}| Code | When to Use |
|---|---|
200 OK | GET, PUT, PATCH success |
201 Created | POST created new resource |
204 No Content | DELETE success, no body |
| Code | When to Use |
|---|---|
400 Bad Request | Invalid request body |
401 Unauthorized | Not authenticated |
403 Forbidden | Authenticated but not allowed |
404 Not Found | Resource doesn't exist |
409 Conflict | Resource conflict (duplicate) |
422 Unprocessable | Validation failed |
429 Too Many | Rate limited |
| Code | When to Use |
|---|---|
500 Internal Error | Unexpected server error |
502 Bad Gateway | Upstream service failed |
503 Unavailable | Service temporarily down |
GET /users?role=admin
GET /users?role=admin&status=active
GET /orders?createdAfter=2024-01-01GET /users?sort=name # Ascending
GET /users?sort=-createdAt # Descending (prefix with -)
GET /users?sort=role,-name # Multiple fieldsGET /users?page=2&perPage=20
GET /users?offset=40&limit=20
GET /users?cursor=abc123 # Cursor-basedGET /users?fields=id,name,email
GET /users?include=orders,profileGET /v1/users
GET /v2/usersGET /users
Accept: application/vnd.api+json;version=2Authorization: Bearer eyJhbGciOiJIUzI1NiIs...X-API-Key: your-api-key
# or
?apiKey=your-api-keyPOST /users/bulk
{
"create": [{ "name": "John" }, { "name": "Jane" }],
"update": [{ "id": "1", "name": "Updated" }],
"delete": ["2", "3"]
}POST /users/search
{
"query": "john",
"filters": { "role": "admin" },
"sort": { "field": "name", "order": "asc" }
}POST /orders/123/cancel
POST /users/123/verify-email
POST /payments/123/refund## Create User
Create a new user account.
**Endpoint:** `POST /users`
**Authentication:** Required (Bearer token)
**Request Body:**
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| name | string | Yes | User's full name |
| email | string | Yes | Valid email address |
| role | string | No | User role (default: "user") |
**Response:** `201 Created`
\`\`\`json
{
"data": {
"id": "123",
"name": "John Doe",
"email": "[email protected]",
"role": "user",
"createdAt": "2024-01-15T10:30:00Z"
}
}
\`\`\`
**Errors:**
- `400` - Invalid request body
- `409` - Email already exists
- `422` - Validation failed~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.