A unique identifier is a value that addresses exactly one resource within a defined scope, enabling lookup among a larger collection. Its uniqueness is contextual: a value may be unique among books, across an API, or—given a sufficiently large key space—in practice across all resources. section 6.1 section 6.2.2
Design identifiers to remain useful throughout an API’s lifetime:
- Keep them permanent and single-use; never recycle an identifier after deletion, or historical references can point to different resources over time. section 6.2.3
- Make common lookups simple by avoiding URI-reserved characters such as the forward slash. section 6.2.1
- Generate identifiers quickly with predictable performance, rather than repeatedly searching for unused random values. section 6.2.4
- Prefer an ASCII representation such as Crockford’s Base32, which avoids confusing characters, supports case-tolerant decoding, and permits optional hyphens. section 6.3.2 section 6.3.3
- Add a checksum so clients can distinguish a mistyped identifier from a valid identifier that names no existing resource. section 6.2.6
- Choose a predictable fixed size and match it to the required scope: roughly 13 Base32 characters for a type-local identifier or 25 for a UUID-scale identifier. section 6.4.1
Resource creation and lookup
A server can create a book with an identifier such as books/AHM6A83HENMP~ and later serve GET /books/AHM6A83HENMP~. The stored value should omit the checksum and any presentation metadata; validate the incoming identifier and calculate the checksum when returning it. section 6.4.1 section 6.4.5
Listing 6.1 Generating a random Base32-encoded identifier
const crypto = require('crypto');
const base32Encode = require('base32-encode');
function generateId(sizeBytes: number): string { #1
const bytes = crypto.randomBytes(sizeBytes); #2
return base32Encode(bytes, 'Crockford'); #3
}
Generate the identifier from cryptographically random bytes and encode those bytes with Crockford’s Base32. section 6.4.2
Treat identifiers as opaque API values rather than embedded resource descriptions. Use strings for cross-resource references, expect references to become stale after deletion or movement, and add request identifiers for deduplicating sensitive non-idempotent operations when the trade-off is justified. section 13.2 section 26.4








