Build the mental model
Cybersecurity Basics already covered protecting the API key itself. That is necessary but nowhere near sufficient.
A protected key sitting in front of a poorly designed API still leaves real gaps. This lesson covers what real API security requires beyond the key.
Authorization must be checked per resource and per action — a valid key only proves a recognized client, not that this specific access is allowed.
Rate limiting protects against abuse, overload, credential-guessing, and cost spikes — but it is only one defense, not a substitute for the others.
Request validation checks type, length, required fields, and allowed values. Response data minimization means returning only the fields a caller actually needs — never a password hash or internal token.
Webhook signatures live elsewhere
For the specific mechanics of verifying webhook signatures, see the API Integration & Webhooks course — this lesson focuses on the broader shape of API security around it.
API SECURITY PIPELINE (BEYOND THE KEY)
--------------------------------------
CLIENT
|
v
AUTHENTICATED REQUEST (valid key/token)
|
v
API
+-- Authorization check (per resource/action)
+-- Rate limit check
+-- Input validation (type/length/required/allowed)
|
v
BUSINESS LOGIC
|
v
DATABASE
|
v
RESPONSE (minimized -- no password hash, no internal tokens)
|
v
CLIENTConnect it to a real scenario
The function below demonstrates response data minimization directly: given a raw database-shaped object, it returns a cleaned version plus exactly which fields were stripped.
Check against a known-sensitive list
Field names like passwordHash or internalToken are matched against every key on the input; matches are removed and recorded.
Pass everything else through
Everything not on the sensitive list passes into the minimized object unchanged.
Run against a raw user record with passwordHash, internalToken, and internal notes: the minimized output keeps only the three legitimate fields.
Put this before serialization
In a real API, an explicit strip-list like this should sit right before the response is serialized, so a new sensitive field can't leak just because nobody remembered to update the response shape.
API Security Checklist (Beyond the Key)
Try the working example
function minimizeResponse(apiResponse) {
const sensitiveFields = ["passwordHash", "internalToken", "internalNotes", "securityAnswer"];
const removed = [];
const minimized = {};
for (const [key, value] of Object.entries(apiResponse)) {
if (sensitiveFields.includes(key)) {
removed.push(key);
} else {
minimized[key] = value;
}
}
return { minimized, removedFields: removed };
}
const rawUserResponse = {
id: 42,
username: "maria",
email: "maria@example.com",
passwordHash: "$2b$10$abcdefghijklmnopqrstuv",
internalToken: "svc_9f8e7d6c5b4a",
internalNotes: "flagged for manual review 2026-01-02",
};
const result = minimizeResponse(rawUserResponse);
console.log(JSON.stringify(result, null, 2));{
"minimized": {
"id": 42,
"username": "maria",
"email": "maria@example.com"
},
"removedFields": [
"passwordHash",
"internalToken",
"internalNotes"
]
}5-minute try-it
Add a rate-limit simulation: write a small function that takes a list of request timestamps for one client and returns whether they exceeded 5 requests in any 10-second window. Combine its result with minimizeResponse's output to imagine a full request/response cycle.
One important caution
Treating "has a valid API key" as equivalent to "is authorized for this specific resource or action."
Returning a full database row as an API response instead of explicitly selecting only the fields a caller actually needs.
OWASP API Security Project — Digital Privacy & Modern Security