api-design — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited api-design (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
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.
URLs name nouns. Actions are verbs.
Good: POST /users/:id/password-reset Bad: POST /resetUserPassword?id=123
200 success with body201 created (include Location)204 success, no body400 client sent something invalid (bad syntax, bad shape)401 not authenticated403 authenticated but not authorized404 resource doesn't exist (or the caller isn't allowed to know it does)409 conflict (version conflict, duplicate, precondition failed)422 semantic validation failed (body parses but rules reject)429 rate limited5xx server fault — internal detail logged, opaque to callerPick one. Use it everywhere.
{
"error": {
"code": "resource_not_found",
"message": "User [email protected] not found.",
"requestId": "abc123"
}
}code is machine-readable, stable, lowercase_snake.message is human-readable. Safe to surface.requestId lets the caller tell you what went wrong without you reading prod logs.Cursor-based for anything you'll scale. Offset paging breaks under concurrent writes.
GET /messages?cursor=abc&limit=50
→ { items: [...], nextCursor: "xyz" }Any POST that has side-effects and will be retried needs an idempotency key:
POST /payments
Idempotency-Key: <uuid-v4>Server stores the (key → response) for a reasonable TTL. Retries return the cached response, not a second charge.
Prefer additive changes. Add fields; don't remove or rename. When you must break, version:
/v2/...) — simple, explicit, slightly uglyAccept: application/vnd.foo.v2+json) — prettier URLs, slightly opaquePick one per service. Never mix.
String! says "this WILL be present". If you're not sure, it's String (nullable). A lie here cascades.
Connections, edges, pageInfo, cursors. Don't invent your own.
updateUser(input: { name, email, password }) is three different operations glued together. Split them.
Return { user: User | UserNotFoundError | ValidationError } unions where it matters. Generic errors[] at the top is for transport-level fault, not business rules.
requestId. Log it. Return it on errors. Tie logs, metrics, and traces together with it.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.