ULID generator API: sortable 26-character IDs
A ULID packs the same amount of information as a UUID into 26 characters such as 01JB8ZQ7X4T9K2M3N5P6R7S8V0. The first 10 characters are the time in milliseconds and the last 16 are random, so sorting ULIDs as plain text sorts them by creation time.
/v1/ulid?count=3 returns JSON. No key, CORS on, 60 requests a minute./v1/ulid
ULIDs: sortable, 26-character IDs. Change the values and press Send request to call the live API.
Parameters
| Name | Type | What it does | Default |
|---|---|---|---|
count | integer | How many, 1 to 100 | 1 |
Example
Request:
GET https://api.oddlathe.com/v1/ulid?count=3
Response (generated by the real code when these docs were last built; random or time-based values will differ for you):
{
"ulids": [
"01M76NG22YE74801ZT43HG3523",
"01M76NG22Y8XJ85V5EWY6DZ8S7",
"01M76NG22YTTTGYY7BNGHNT7SY"
]
}
Code examples
curl 'https://api.oddlathe.com/v1/ulid?count=3'const params = new URLSearchParams({
count: "3"
});
const res = await fetch(`https://api.oddlathe.com/v1/ulid?${params}`);
if (!res.ok) throw new Error((await res.json()).error.message);
const data = await res.json();
console.log(data);import json, urllib.parse, urllib.request
params = urllib.parse.urlencode({"count": "3"})
url = "https://api.oddlathe.com/v1/ulid?" + params
# Send a User-Agent: the edge network refuses Python's default one.
req = urllib.request.Request(url, headers={"User-Agent": "my-script/1.0"})
with urllib.request.urlopen(req, timeout=10) as r:
data = json.load(r)
print(data)When it's useful
- Keys in key-value stores or file names where alphabetical order should equal time order
- Short, URL-safe IDs without hyphens
- Log or event IDs that you want to scan in time order
Good to know
- Crockford base32 leaves out I, L, O and U so IDs are easy to read aloud and hard to mistype.
- IDs made in the same millisecond share the time part and differ only in the random part; their relative order inside that millisecond is random.
- ULIDs fit in a 128-bit UUID column if you decode them, but most people store them as text.
48-bit millisecond time + 80 random bits in Crockford base32. Lexicographically sortable and URL-safe.
Errors
Errors are JSON like {"error": {"code": "…", "message": "…"}}. The ones this endpoint can return:
bad_param(400): a value is the wrong type or out of range (the message says which)rate_limited(429): over 60 requests a minute; wait for Retry-After seconds
Questions
ULID or UUID v7?
They carry the same idea. Pick UUID v7 if your database has a native UUID type; pick ULID if you store IDs as text and want them shorter and without hyphens.
Do ULIDs leak information?
They reveal the creation time to the millisecond, nothing else.
Related endpoints
/v1/uuidRandom UUIDs (v4) or time-ordered UUIDs (v7)/v1/nanoidShort URL-safe random IDs (21 chars, 126 bits)
Published · OpenAPI 3.1 spec · Limits and privacy