Docs / Developer tools
Developer utilities API
Cron in words, UUIDs and ULIDs, hashes and HMACs, JWT decoding, user agents and time zones.
Small tools a program or an assistant needs often. Times are in India time unless you name a zone.
https://api.dharun.devNo key needed for most600 units a minute, 3000 with a free keyThis page as MarkdownExplain a cron expression
GET/v1/cron
The expression in words and its next run times.
| Parameter | Description |
|---|---|
exprquery, required | Five fields, or @daily, @hourly, @weekly, @monthly, @yearly. |
tzquery | Time zone the schedule runs in. Default Asia/Kolkata. |
countquery | Next runs, 1 to 50. Default 5. |
fromquery | Start from this time instead of now. |
curl
curl "https://api.dharun.dev/v1/cron?expr=30%209%20*%20*%201-5&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/cron?expr=30%209%20*%20*%201-5&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/cron?expr=30%209%20*%20*%201-5&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
New UUIDs, ULIDs and nano ids
GET/v1/uuid
| Parameter | Description |
|---|---|
kindquery | Default uuid4. One of: uuid4, uuid7, ulid, nanoid. |
countquery | 1 to 100. Default 1. |
curl
curl "https://api.dharun.dev/v1/uuid?kind=uuid7&count=3&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/uuid?kind=uuid7&count=3&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/uuid?kind=uuid7&count=3&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Read a UUID or ULID
GET/v1/uuid/{id}
Its version and variant, and the time inside a version 1 or 7 UUID or a ULID.
| Parameter | Description |
|---|---|
idpath, required | The UUID or ULID. |
curl
curl "https://api.dharun.dev/v1/uuid/01936f4e-5a6a-7cc2-9a4b-3e5b2a1f0c11?utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/uuid/01936f4e-5a6a-7cc2-9a4b-3e5b2a1f0c11?utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/uuid/01936f4e-5a6a-7cc2-9a4b-3e5b2a1f0c11?utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response
{
"data": {
"kind": "uuid",
"version": 7,
"variant": "RFC 9562",
"time": "2024-11-27T20:27:06.218Z"
},
"meta": {}
}Hashes and HMACs
GET/v1/hashPOST
MD5, SHA-1, SHA-2, SHA-3, BLAKE2b and CRC-32 of a text, in hex and base64; with key, HMACs.
Also takes POST: The text, as text/plain, or JSON {"text": "...", "algo": "sha256", "key": "..."}. Send it as text/plain, or as JSON {"text": "..."} with the other options beside it, up to 256 KB.
What you send here is never written to the log, and the answer is not cached.
| Parameter | Description |
|---|---|
textquery | The text. |
algoquery | Comma-separated: md5, sha1, sha256, sha384, sha512, sha3-256, sha3-512, blake2b-256, crc32. Default md5,sha1,sha256,sha512. |
keyquery | For an HMAC. Send it in a POST body. |
curl
curl "https://api.dharun.dev/v1/hash?text=hello&algo=sha256,md5&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/hash?text=hello&algo=sha256,md5&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/hash?text=hello&algo=sha256,md5&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response
{
"data": {
"md5": {
"hex": "5d41402abc4b2a76b9719d911017c592",
"base64": "XUFAKrxLKna5cZ2REBfFkg=="
},
"sha256": {
"hex": "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
"base64": "LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="
}
},
"meta": {
"note": "Digests of the text's UTF-8 bytes."
}
}Decode a JWT
GET/v1/jwt/decodePOST
The header, payload and times of a JSON Web Token. The signature is not checked.
Also takes POST: The token, as text/plain or JSON {"text": "..."}. Send it as text/plain, or as JSON {"text": "..."} with the other options beside it, up to 256 KB.
What you send here is never written to the log, and the answer is not cached.
| Parameter | Description |
|---|---|
textquery | The token. |
curl
curl "https://api.dharun.dev/v1/jwt/decode?text=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkZW1vIiwiaWF0IjoxNzYyODQ4MDAwfQ.c2ln&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/jwt/decode?text=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkZW1vIiwiaWF0IjoxNzYyODQ4MDAwfQ.c2ln&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/jwt/decode?text=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkZW1vIiwiaWF0IjoxNzYyODQ4MDAwfQ.c2ln&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Response
{
"data": {
"header": {
"alg": "HS256"
},
"payload": {
"iat": 1762848000,
"sub": "demo"
},
"signature": "c2ln",
"times": {
"iat": "2025-11-11T08:00:00Z"
},
"warnings": []
},
"meta": {
"note": "Decoded only: the signature is NOT checked, so nothing here proves who made the token. Never paste a live token you do not own."
}
}Read a user agent
GET/v1/user-agent
Browser, engine, system, device and vendor, and whether it is a person, an AI assistant, a crawler or a program. Without ua, your own request's.
| Parameter | Description |
|---|---|
uaquery | A User-Agent header. Default: yours. |
curl
curl "https://api.dharun.dev/v1/user-agent?ua=Mozilla%2F5.0%20(Linux%3B%20Android%2014%3B%20SM-S918B)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F131.0.0.0%20Mobile%20Safari%2F537.36&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/user-agent?ua=Mozilla%2F5.0%20(Linux%3B%20Android%2014%3B%20SM-S918B)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F131.0.0.0%20Mobile%20Safari%2F537.36&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/user-agent?ua=Mozilla%2F5.0%20(Linux%3B%20Android%2014%3B%20SM-S918B)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F131.0.0.0%20Mobile%20Safari%2F537.36&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Convert a time between zones
GET/v1/time
"3 pm IST in Berlin": a time read many ways (2026-11-11 15:00, 3pm, a Unix time) in one zone, shown in others with their offsets and the day difference.
| Parameter | Description |
|---|---|
atquery | The time. Default now. |
fromquery | Its zone: IANA name, short name, city or offset. Default India. |
toquery | Zones to show it in, separated by commas. Default UTC. |
curl
curl "https://api.dharun.dev/v1/time?at=2026-11-11%2015%3A00&from=IST&to=Europe%2FBerlin,PST,SGT&utm_medium=docs"JavaScript
const response = await fetch("https://api.dharun.dev/v1/time?at=2026-11-11%2015%3A00&from=IST&to=Europe%2FBerlin,PST,SGT&utm_medium=docs");
const body = await response.json();
if (!response.ok) throw new Error(body.error.message);
console.log(body.data);Python
import requests
response = requests.get("https://api.dharun.dev/v1/time?at=2026-11-11%2015%3A00&from=IST&to=Europe%2FBerlin,PST,SGT&utm_medium=docs", timeout=10)
body = response.json()
if not response.ok:
raise RuntimeError(body["error"]["message"])
print(body["data"])Try it here
Change the values and send the request from your browser. Needs JavaScript.
Using an AI assistant? Connect the MCP server and it can call this API by itself. Want every endpoint on one bench? Open the playground.