Free Public REST APIs

Utility endpoints for time, randomness, encoding, JSON, CSV and image conversion, hashing, web lookups, webhooks and crypto - with no API key, no sign-up and no cost. Drop a URL into curl, Python, JavaScript or an LLM tool definition and it works.

Base URL: https://aisenseapi.com/services/v1 - Open source client libraries and tests: github.com/aisenseapi/aisense-free-public-rest-apis

Rate limit: 5000 requests per IP address per day, REST and MCP together. The count resets at midnight Norwegian time (Europe/Oslo), which is 22:00 UTC in summer and 23:00 UTC in winter, and a 429 answer carries Retry-After with the seconds until then.

Connecting an AI agent?

The MCP server at https://aisenseapi.com/mcp offers every endpoint on this page as a tool, and the workflow tools, including Agent Queue, Heartbeat, Lease, Agent Inbox, Agent Wake and the temporary DNS name tools.

For Verifyum alone, connect directly to https://api.verifyum.com/mcp. It needs no account or API key, and file hashing stays on the agent's machine.

To reach another agent rather than a tool, aamio is at https://aamio.at/mcp. A thread there expires at a fixed time, and the open board at https://board.aamio.at/ is where agents that have never met find each other.

See the MCP tool list and client examples.

Delegating work to another agent?

Agent2Agent revision 1.0 answers at https://aisenseapi.com/a2a over JSON-RPC 2.0, with the agent card at https://aisenseapi.com/.well-known/agent-card.json. No account, no API key.

A2A carries the five task-shaped capabilities only: agent-wake, human-approval, agent-inbox, webhook-capture and agent-queue. Other endpoints remain on REST. MCP exposes a selected set of workflow tools with schemas returned by discovery. Queue is reachable on all three surfaces; its read and worker operations stay on REST and MCP.

A2A skills carry no id on the wire and no input schema, so the caller names one inside the message, in a part carrying structured data: {"skill": "agent-wake", "arguments": {}}. That is a convention this service documents rather than something the protocol defines, and an agent with no language model refuses a message without it.

See the A2A skills, methods and response shapes.

Need a public file proof?

Verifyum creates free file proofs on Solana Mainnet over HTTP or MCP. The original file stays local, and the service receives only a privacy-preserving commitment.

An agent can anchor one local decision record containing its instructions, prompt, model, parameters, tool calls and output. The proof shows that the record existed unchanged by the block time. It does not prove that the agent ran with the recorded settings.

The Solana transaction is the primary evidence. OpenTimestamps on Bitcoin, a qualified EU timestamp, witness-cosigned Sigsum and Certificate Transparency provide independent corroboration. Verifyum's signature, GitHub, Software Heritage and Internet Archive are operator or availability records. Check the public receipt before describing a channel as confirmed.

New finalized proofs are announced on Telegram and in the Atom feed. These announcements are excluded from the evidence records.

Read about Verifyum or inspect the Witness Layer.

Detailed API guides

Each guide includes request formats, response fields, curl examples and common errors.

The robot after a service name means Agent Optimal: built for agent workflows. This is an AI SENSE label, not an independent certification or a live service-status indicator.

Before you write a client

Three service-wide behaviours decide how your error handling has to look.

The response key is named after the endpoint.
There is no generic data or result wrapper. /md5_hash returns md5_hash, /ping returns ping, /random_color returns random_color. Each endpoint below states its key. The Convert and Images endpoints are the exception: they store their result and answer with the Storage fields.
Check both the HTTP status and the error field.
Errors usually use {"error": "message"} with a non-2xx status. The legacy wallet-generation handlers can return an error object with HTTP 200. Workflow endpoints use non-2xx errors, including 409 for conflicts, 410 for expired records not yet removed, and 503 for temporary storage problems. Unknown or removed records return 404. Each endpoint lists its additional errors.
Not everything is JSON.
The three decoders return application/octet-stream unless you send Accept: application/json.

Time

See the time API guide for datetime, timestamp and timezone examples.

Datetime REST API Endpoint

GET /datetime[/{offset}] - /datetime/{zone}

Current date and time in ISO 8601. The optional offset is a four-digit UTC offset with an optional sign - +0200, -0530 or 0100 - or +02:00. An hour-only value such as 1 is not a valid route. An IANA zone such as europe/oslo, in any case, follows summer time and answers the zone, its abbreviation, the offset in force, whether summer time is on and when it starts and ends, the day and week numbers and the time in UTC as well. Clients of WorldTimeAPI find which path answers each of theirs on the WorldTimeAPI alternative page.

curl https://aisenseapi.com/services/v1/datetime/+0200

{ "datetime": "2026-08-16T11:44:35+02:00" }

IP Datetime REST API Endpoint

GET /ip_datetime[/{ip}]

The time where an IPv4 or IPv6 address is: ip, then the same fields as /datetime/{zone} for the zone an address lookup places it in. Without an address, the caller's own. An address with no zone known, such as a private one, is HTTP 404.

curl https://aisenseapi.com/services/v1/ip_datetime/8.8.8.8

{"ip":"8.8.8.8","datetime":"2026-10-03T05:41:07-05:00","timezone":"America/Chicago","abbreviation":"CDT","utc_offset":"-05:00","dst":true, ...}

Timestamp REST API Endpoint

GET /timestamp

Current Unix timestamp in seconds. Response key: timestamp.

{ "timestamp": 1786873261 }

Microtimestamp REST API Endpoint

GET /microtimestamp

Unix timestamp with microsecond precision. Response key: microtimestamp.

{ "microtimestamp": 1786873474.745043 }

Timezones REST API Endpoint

GET /timezones[/{offset}]

All available timezones, optionally filtered by a four-digit offset. The list contains objects, not strings.

{
  "timezones": [
    { "timezone": "Africa/Abidjan",  "offset": "+0000" },
    { "timezone": "Africa/Blantyre", "offset": "+0200" }
  ]
}

Swatchinternettime REST API Endpoint

GET /swatchinternettime

Swatch Internet Time. The day is divided into 1000 .beats of 86.4 seconds each, based on Biel Meantime, with no time zones. beat is a string with a leading @, not a number.

{ "beat": "@444", "date": "2026-08-16" }

Timestamp Convert REST API Endpoint

POST /timestamp_convert

One time value in, every representation out. Accepts unix seconds, unix milliseconds (13 digits and up, the Date.now() format, detected automatically), ISO 8601, RFC 2822, or "now". The optional offset uses the same four digit form as /datetime. Bad input returns HTTP 400.

Request:  { "data": "1700000000123", "offset": "+0100" }

Response: { "input": "1700000000123", "detected": "unix_ms", "timestamp": 1700000000,
  "datetime": "2023-11-14T23:13:20+01:00", "rfc2822": "Tue, 14 Nov 2023 23:13:20 +0100",
  "utc_datetime": "2023-11-14T22:13:20+00:00" }

Random

See the random generator API guide for UUID, GUID, password, number and color endpoints.

Random Number REST API Endpoint

GET /random_number[/{from}[/{to}]]

Random integer, inclusive of both bounds. No arguments gives 1 - 6. A single argument is treated as the upper bound with the lower bound fixed at 1.

curl https://aisenseapi.com/services/v1/random_number/1/100

{ "random_number": 73, "range": { "from": 1, "to": 100 } }

Random Color REST API Endpoint

GET /random_color

Random hex color, always six digits. Response key: random_color.

{ "random_color": "#9b6bbf" }

UUID REST API Endpoint

GET /uuid

Generate a UUID version 4. Response key: uuid.

{ "uuid": "429151ee-82a1-4438-b2f1-b6b9c9e4a41f" }

GUID REST API Endpoint

GET /guid

Generate a GUID. Response key: guid.

{ "guid": "750dd9a6-a507-4a89-b4ec-8cd71fc115b7" }

Password REST API Endpoint

GET /password[/{length}]

Random password including punctuation, twelve characters by default.

curl https://aisenseapi.com/services/v1/password/16

{ "password": "jFehS]AKGx9wl[jp", "password_length": 16 }

Passphrase REST API Endpoint

GET /passphrase[/{groups}]

Pronounceable passphrase, four hyphen separated groups by default, 2 to 12 allowed. The argument counts groups, not characters.

curl https://aisenseapi.com/services/v1/passphrase/4

{ "passphrase": "hudil-rosi4-Zerzo-Coze#", "groups": 4, "length": 23, "entropy_bits": 91.4 }

Transform

All Transform endpoints are POST and accept JSON, plain text with Content-Type: text/plain, or a file upload.

Use the encoding API guide for Base32, Base58 and Base64. The QR code API guide covers image encoding and decoding.

Base64 Encode REST API Endpoint

POST /base64_encode

{ "data": "Hello world" }

{ "base64_encoded_data": "SGVsbG8gd29ybGQ=" }

Base64 Decode REST API Endpoint

POST /base64_decode

Returns the decoded bytes as application/octet-stream - the payload and nothing else. Send Accept: application/json to get a typed envelope instead.

# default: raw bytes
Request:  { "data": "SGVsbG8gd29ybGQ=" }
Response: Hello world

# with Accept: application/json
{ "data": "eyJrZXkiOiJ2YWx1ZSJ9" }
Response: { "type": "json", "decoded_data": { "key": "value" } }

# non-JSON content, with Accept: application/json
Response: { "type": "binary", "encoding": "base64", "decoded_data": "iVBORw0KGgo..." }

Base58 Encode REST API Endpoint

POST /base58_encode

Request:  { "data": "Hello" }
Response: { "base58_encoded_data": "9Ajdvzr" }

Base58 Decode REST API Endpoint

POST /base58_decode

Same Accept behaviour as Base64 Decode. An invalid Base58 character returns HTTP 400 with {"error": "Invalid Base58 input."}.

Request:  { "data": "9Ajdvzr" }
Response: Hello

Base32 Encode REST API Endpoint

POST /base32_encode

Request:  { "data": "Hello" }
Response: { "base32_encoded_data": "JBSWY3DP" }

Base32 Decode REST API Endpoint

POST /base32_decode

Same Accept behaviour as Base64 Decode.

Request:  { "data": "JBSWY3DP" }
Response: Hello

Hex Encode REST API Endpoint

POST /hex_encode

Any bytes to lower-case hex. Response key: hex_encoded_data.

Request:  { "data": "hello" }
Response: { "hex_encoded_data": "68656c6c6f" }

Hex Decode REST API Endpoint

POST /hex_decode

Hex in either case, with an optional 0x and spaces, back to bytes. Same Accept behaviour as Base64 Decode.

Request:  { "data": "68656C6C6F" }
Response: hello

base64url Encode REST API Endpoint

POST /base64url_encode

The URL-safe alphabet, - and _, without padding, as JWT writes it. Response key: base64url_encoded_data.

Request:  { "data": "hello?" }
Response: { "base64url_encoded_data": "aGVsbG8_" }

base64url Decode REST API Endpoint

POST /base64url_decode

With or without padding. Same Accept behaviour as Base64 Decode; a + or / is HTTP 400.

Request:  { "data": "aGVsbG8_" }
Response: hello?

URL Encode REST API Endpoint

POST /url_encode

RFC 3986 percent-encoding for one path segment or query value: a space is %20. Response key: url_encoded_data.

Request:  { "data": "a b/c?é" }
Response: { "url_encoded_data": "a%20b%2Fc%3F%C3%A9" }

URL Decode REST API Endpoint

POST /url_decode

Percent-encoding back to UTF-8 text; a + stays a +. Response key: url_decoded_data.

Request:  { "data": "a%20b%2Fc+%C3%A9" }
Response: { "url_decoded_data": "a b/c+é" }

HTML Encode REST API Endpoint

POST /html_encode

& < > " ' as entities, so text can go into a page or an attribute. Response key: html_encoded_data.

Request:  { "data": "<b>Tom & Jerry</b>" }
Response: { "html_encoded_data": "&lt;b&gt;Tom &amp; Jerry&lt;/b&gt;" }

HTML Decode REST API Endpoint

POST /html_decode

Every named HTML5 entity and every numeric one back to its character. Response key: html_decoded_data.

Request:  { "data": "&lt;b&gt; &eacute;" }
Response: { "html_decoded_data": "<b> é" }

HTML to Markdown REST API Endpoint

POST /html_to_markdown

A web page or any HTML as CommonMark with GitHub tables, without scripts, styles, forms or media, and the page title. At most 1 MiB and 40000 tags. Response keys: markdown, title.

Request:  { "data": "<h1>Hi</h1><p>A <b>bold</b> word</p>" }
Response: { "markdown": "# Hi\n\nA **bold** word", "title": null }

Markdown to HTML REST API Endpoint

POST /markdown_to_html

CommonMark with GitHub tables, strikethrough and task lists to an HTML fragment that is safe to put in a page: raw HTML is shown as text and a link with an unsafe scheme as its text. At most 256 KiB and 20000 lines. Response key: html.

Request:  { "data": "**Bold** <b>raw</b>" }
Response: { "html": "<p><strong>Bold</strong> &lt;b&gt;raw&lt;/b&gt;</p>" }

Slugify REST API Endpoint

POST /slugify

Text to URL slug. Scandinavian letters and common Latin diacritics are transliterated by a fixed table, so the same input gives the same slug on every machine. Input with no sluggable characters returns HTTP 400 rather than an empty slug.

{ "data": "Blåbærsyltetøy på Ås!" }   ->   { "slug": "blabaersyltetoy-pa-as" }

JWT Encode REST API Endpoint

POST /jwt_encode

Encodes claims into an HS256 JSON Web Token. data takes the claims as a JSON object directly, or as a string containing JSON - both forms produce the same token. A string that does not parse as JSON returns HTTP 400.

{ "data": { "user": "alice" }, "secret": "your_secret_key" }          # object form
{ "data": "{\"user\":\"alice\"}", "secret": "your_secret_key" }      # string form, same token

{ "jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWxpY2UifQ..." }

Also accepts plain text with an X-Secret header, or a file upload in a jwt_data field.

JWT Decode REST API Endpoint

POST /jwt_decode

{ "data": "eyJ0eXAiOiJKV1Qi...", "secret": "your_secret_key" }

{ "decoded_payload": { "user": "alice" } }

QR Code Encode REST API Endpoint

POST /qrcode_encode

Generates a QR code as a Base64 PNG. Encodes URLs, plain text, vCards, Wi-Fi credentials and calendar events. The request field is payload, with data accepted as an alias.

{ "payload": "https://aisenseapi.com/" }

{ "qrcode_image": "iVBORw0KGgoAAAANSUhEUg...", "image_type": "png" }

QR Code Decode REST API Endpoint

POST /qrcode_decode

Accepts a Base64 image in the payload field, or a file upload in a qrcode_image field.

{ "payload": "iVBORw0KGgoAAAANSUhEUg..." }

{ "qrcode_content": "https://aisenseapi.com/" }

Convert

All Convert endpoints are POST with a JSON body of at most 256 KB. None of them returns the result in the answer. Each one stores its result in Storage for 24 hours and answers with the Storage fields plus content_type, filename and operation. Read the result with a GET on storage_url. Anyone with that link can read it, and stored results count against the Storage budget of 80 MB per IP address per day.

The answer to the JSON to CSV example below, from a test run. The id and the expiry are different on every call:

{
  "storage_id": "b5b3016f-52df-43a7-801c-7b7d0baa4b94",
  "storage_url": "https://aisenseapi.com/services/v1/storage/b5b3016f-52df-43a7-801c-7b7d0baa4b94",
  "sha256_hash": "3e749b9bff583e347820dee8435476eca0ca58fe2e4639c53cc13c8cc9925c1c",
  "bytes": 44,
  "expire_timestamp": 1790760065,
  "expire_datetime": "2026-09-30T09:21:05+00:00",
  "content_type": "text/csv; charset=utf-8",
  "filename": "result.csv",
  "operation": "json_to_csv"
}

JSON to CSV REST API Endpoint

POST /json_to_csv

JSON records to CSV, with the columns in the order you name them. Every cell is quoted, text such as 00123 stays text, and nested values are refused. Optional delimiter (comma, semicolon or tab) and spreadsheet_safe. Guide and browser tool.

{"columns": ["customer_id", "name"], "rows": [{"customer_id": "00123", "name": "Nordlys AS"}], "delimiter": ";"}

# stored as result.csv
"customer_id";"name"
"00123";"Nordlys AS"

CSV to JSON REST API Endpoint

POST /csv_to_json

CSV text to JSON with the column names and one object per row. Every cell stays a string. The first line is the header, and malformed quoting or a row of the wrong width is refused rather than guessed at. Guide and browser tool.

{"data": "customer_id,name\n00123,Nordlys AS\n"}

# stored as result.json
{"columns":["customer_id","name"],"rows":[{"customer_id":"00123","name":"Nordlys AS"}]}

Table Matching REST API Endpoint

POST /table_match

Compares two lists of rows on one or more pairs of key columns. Every row lands in matched, only_left, only_right or ambiguous, and duplicate keys are reported, never paired at random. Keys are compared exactly. Guide and browser tool.

{"left": [{"id": "1"}, {"id": "2"}], "right": [{"id": "2"}, {"id": "3"}], "keys": [{"left": "id", "right": "id"}]}

# stored as matches.json
{"matched":[{"left_index":1,"right_index":0}],"only_left":[0],"only_right":[1],"ambiguous":[]}

JSON Format REST API Endpoint

POST /json_format

Pretty prints or minifies JSON text sent as a string. Only whitespace changes, so number spelling, escapes, key order and duplicate keys stay as sent. Invalid JSON answers 400. Guide and browser tool.

{"data": "{\"price\":1.50,\"tags\":[\"a\"]}", "mode": "pretty"}

# stored as result.json
{
  "price": 1.50,
  "tags": [
    "a"
  ]
}

JSON Validate REST API Endpoint

POST /json_validate

Checks JSON syntax. Invalid JSON is a result, not an error: the answer adds valid, and the stored report carries the parser message. Guide and browser tool.

{"data": "{\"a\":1,}"}

# stored as validation.json
{"valid":false,"error":"Syntax error","input_bytes":8,"max_depth":128}

Images

All seven image endpoints are POST with multipart/form-data: the image in a field named file, a JPEG, PNG or WebP of at most 10 MB, and the options as form fields. image_convert and image_resize also read HEIC. Like the Convert endpoints, they store the result in Storage for 24 hours and answer with the Storage fields, plus operation and what the result is.

image_convert, image_compress, image_resize, image_colors and image_favicon decode the image, so it may be at most 25 megapixels. ImageMagick does that work in a sandbox without network access, two images at a time. Every converted image is turned upright, and EXIF, XMP, IPTC and comments are removed while the color profile is kept. image_metadata and image_strip only read and rewrite the file, so they have no pixel limit and never change a pixel.

The answer to the image_convert example below, from a test run with a test image of 1600 x 1200 pixels. The id, the expiry and the sizes differ from call to call and image to image:

{
  "storage_id": "1ddd4269-b51c-4209-a4de-6908926f672b",
  "storage_url": "https://aisenseapi.com/services/v1/storage/1ddd4269-b51c-4209-a4de-6908926f672b",
  "sha256_hash": "97350f282284446cbb19db5a0695a654e0162fafd52db766fb12099b6497202d",
  "bytes": 195648,
  "expire_timestamp": 1790767674,
  "expire_datetime": "2026-09-30T11:27:54+00:00",
  "content_type": "image/webp",
  "filename": "result.webp",
  "operation": "image_convert",
  "format": "webp",
  "width": 1600,
  "height": 1200,
  "input_format": "jpeg",
  "input_bytes": 641358
}

Image Convert REST API Endpoint

POST /image_convert

Converts between JPEG, PNG and WebP, and reads HEIC from an iPhone, turned the way the phone stored it. format is required. quality, 40 to 95 and 82 by default, applies to JPEG and WebP, and lossless=true makes a lossless WebP. Transparent pixels become white in a JPEG. Guide and browser tool, and a HEIC to JPG converter for iPhone photos.

curl -s -X POST https://aisenseapi.com/services/v1/image_convert \
  -F "file=@photo.jpg" \
  -F "format=webp"

Image Compress REST API Endpoint

POST /image_compress

Saves a JPEG, PNG or WebP again in its own format. JPEG and WebP take a quality, which is lossy; PNG is saved again losslessly. input_bytes and bytes in the answer show what was saved. Guide and browser tool.

curl -s -X POST https://aisenseapi.com/services/v1/image_compress \
  -F "file=@photo.jpg" \
  -F "quality=70"

Image Resize REST API Endpoint

POST /image_resize

Gives a JPEG, PNG, WebP or HEIC a new width, height or both. fit=contain keeps all of the picture inside the box, and fit=cover fills it and cuts the rest from the centre, for thumbnails. Nothing is enlarged unless upscale=true. The answer adds input_width, input_height, fit and upscaled. Guide and browser tool.

curl -s -X POST https://aisenseapi.com/services/v1/image_resize \
  -F "file=@photo.jpg" \
  -F "width=800"

Image Metadata REST API Endpoint

POST /image_metadata

Reports what an image carries besides its pixels: EXIF with the GPS position in decimal degrees, XMP, IPTC, the color profile, comments, thumbnails and data after the image, with a privacy summary. The report is stored as metadata.json, and the answer adds format, width, height, gps and findings. Guide and browser tool.

curl -s -X POST https://aisenseapi.com/services/v1/image_metadata \
  -F "file=@photo.jpg"

Image Strip REST API Endpoint

POST /image_strip

Removes EXIF, GPS, XMP, IPTC and comments without saving the image again: the image data is copied byte for byte. The color profile is kept, and so is the orientation, written back alone. The answer adds removed and kept. Guide and browser tool.

curl -s -X POST https://aisenseapi.com/services/v1/image_strip \
  -F "file=@photo.jpg"

Image Colors REST API Endpoint

POST /image_colors

The dominant colors of an image with the share each covers, the average color and a 16 pixel placeholder as a data URI, stored as colors.json. count is 2 to 16, and 8 by default. The answer adds average, dominant and count. Guide and browser tool.

curl -s -X POST https://aisenseapi.com/services/v1/image_colors \
  -F "file=@photo.jpg" \
  -F "count=6"

Image Favicon REST API Endpoint

POST /image_favicon

A ZIP with favicon.ico, PNG icons from 16 to 512 pixels, an iOS icon, a web manifest and the head tags. crop is fit, trim or center, and name goes into the manifest. The answer adds files, crop and upscaled. Guide and browser tool.

curl -s -X POST https://aisenseapi.com/services/v1/image_favicon \
  -F "file=@logo.png" \
  -F "crop=trim" \
  -F "name=Example site"

Logic

/decide answers typed questions from rules by default, with optional model selection. /mock_response answers with the response you pick for client tests.

Decision API EndpointAgent Optimal

POST /decide

Send a state and named rule questions: yes_no, choice or scale. Rule answers include probabilities, confidence, action and because. Omit model to keep this behavior. Optional "model" clef, nimble or tev1 uses instructions and criteria and its own question types, has its own per-IP usage limit and gives no automatic action. See the guide for its format, availability and data handling.

curl -s -X POST https://aisenseapi.com/services/v1/decide   -H "Content-Type: application/json"   -d '{"state": {"amount": 30}, "questions": {"refund": {"type": "yes_no", "bias": -1, "rules": [{"if": {"amount": {"lte": 50}}, "weight": 3}]}}}'
{"answers": {"refund": {"type": "yes_no", "answer": "yes", "probability": 0.8808, "confidence": 0.7616, "action": "review", "because": [{"rule": 0, "weight": 3}]}}}

Mock Response API Endpoint

ANY /mock_response/{status}[/{ms}]

Answers with the status in the path, at once or after up to 10000 milliseconds, with the headers a real service sends: Retry-After on 429 and 503, WWW-Authenticate on 401. /mock_response/html, /mock_response/empty and /mock_response/wrongtype give broken answers. Any method works, and the body and the query string are not read.

curl -s https://aisenseapi.com/services/v1/mock_response/503
{"error":"Service Unavailable","mock_response":{"status":503,"delay_ms":0}}

Hash

All hash endpoints are POST and accept JSON, plain text or a file upload. Each returns a key named after the algorithm - never hash.

See the hashing API guide for all five algorithms and input formats.

Hash endpoints, response keys and example digests
EndpointResponse keyDigest of "Hello"
/md5_hashmd5_hash8b1a9953c4611296a827abf8c47804d7
/sha1_hashsha1_hashf7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0
/sha256_hashsha256_hash185f8db32271fe25f561a6fc938b2e26...
/sha512_hashsha512_hash3615f80c9d293ed7402687f94b22d58e...
/sha3_256_hashsha3_256_hash8ca66ee6b2fe4bb928a8e3cd2f508de4...
/sha3_512_hashsha3_512_hash0b8a44ac991e2b263e8623cfbeefc1cf...
/blake2b_hashblake2b_hash8b7ca7d27d9fc55fa30abfe515b3afb2...
/whirlpool_hashwhirlpool_hash00acca7b4456c52a74c589d668b48e1b...
/blake3_hashblake3_hashfbc2b0516ee8744d293b980779178a35...
/argon2id_hashargon2id_hash$argon2id$v=19$m=65536,t=3,p=1$...
/bcrypt_hashbcrypt_hash$2b$12$...
/scrypt_hashscrypt_hash$scrypt$ln=17,r=8,p=1$...
/crc32_checksumcrc32_checksum4157704578

MD5, SHA1, SHA256, SHA512, SHA3, BLAKE2b, BLAKE3 and Whirlpool Hash REST API Endpoints, and Argon2id, bcrypt and scrypt Password Hashes

POST /md5_hash - /sha1_hash - /sha256_hash - /sha512_hash - /sha3_256_hash - /sha3_512_hash - /blake2b_hash - /whirlpool_hash

curl -X POST https://aisenseapi.com/services/v1/sha256_hash \
  -H "Content-Type: application/json" -d '{"data": "Hello"}'

{ "sha256_hash": "185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969" }

CRC32 Checksum REST API Endpoint

POST /crc32_checksum

Returns an integer, not a hex string.

Request:  { "data": "Hello" }
Response: { "crc32_checksum": 4157704578 }

Hash Verify REST API Endpoint

POST /hash_verify

Verify data against a hash from any endpoint above. Name the algorithm in an algorithm field when you know it, and always for sha3_256, sha3_512, blake2b and whirlpool, whose lengths collide with sha256 and sha512. Without the field the algorithm is recognized from the hash itself: an integer means crc32, hex strings map by length (8 crc32, 32 md5, 40 sha1, 64 sha256, 128 sha512). A mismatch is a result with match: false, and computed is always included so the difference is visible. JSON only.

Request:  { "data": "Hello", "hash": "185f8db32271fe25f561a6fc938b2e26..." }

Response: { "match": true, "algorithm": "sha256", "computed": "185f8db3..." }

Web

Ping REST API Endpoint

GET /ping

Connectivity check. Response key: ping.

{ "ping": "pong" }

Health REST API Endpoint

GET /health

Service health with a high-precision timestamp. The second key is microtimestamp, not timestamp.

{ "status": "ok", "microtimestamp": 1786873258.589068 }

Client IP REST API Endpoint

GET /client_ip

The public IP address of the caller.

{ "ip": "203.0.113.42" }

User Agent REST API Endpoint

GET /user_agent

{ "user_agent": "curl/8.5.0" }

IP Reverse Lookup REST API Endpoint

GET /ip_reverse_lookup/{ip}

Geolocates an IP address. city and place are frequently null, and the coordinates fall back to the country centroid when the city is unknown. Latitude and longitude are strings.

curl https://aisenseapi.com/services/v1/ip_reverse_lookup/8.8.8.8

{
  "ip": "8.8.8.8",
  "country": "United States",
  "city": null,
  "location": { "lat": "37.751000", "lng": "-97.822000" },
  "place": null,
  "timezone": "America/Chicago"
}

Domain IP Lookup REST API Endpoint

GET /domain_ip_lookup/{domain}

{ "domain": "example.com", "ip": "104.20.23.154" }

Email Validate REST API Endpoint

POST /email_validate

Syntax check, then DNS through the host resolver - nothing goes to a third party. has_mx means the domain publishes MX records; has_address_record covers the RFC 5321 fallback, so a missing MX alone does not prove an address dead. A failing address is a result with valid_syntax: false, and the endpoint never opens an SMTP conversation.

Request:  { "data": "test@gmail.com" }

Response: { "email": "test@gmail.com", "valid_syntax": true, "domain": "gmail.com",
  "has_mx": true, "mx_hosts": ["gmail-smtp-in.l.google.com", "..."], "has_address_record": true }

Validate REST API Endpoint

POST /validate/{type}

Check-digit validation for iban, card, orgnr, kontonummer and phone. Pure arithmetic - nothing is looked up, so valid means well-formed with a correct check digit. An invalid value is a result with valid: false, and the card number is never echoed back. Full details.

POST /validate/iban   { "data": "NO9386011117947" }
  ->  { "type": "iban", "valid": true, "country": "NO", "checksum_ok": true }

Storage REST API Endpoint

POST /storage - GET /storage/{storage_id}

Temporary key-value storage for JSON, text or files. Post any body, get a UUID, retrieve it from anywhere - another machine, a later pipeline step, a different agent call. No database to set up and no sign-up. The storage_id is the only thing that reads the item, so treat its URL as a capability link and send it only to the intended recipient.

The body is stored verbatim: whatever you send is exactly what comes back, with no wrapper added or removed. Everything expires after 24 hours.

The answer carries the link to hand on and the digest of the bytes as stored. Put that digest in the link, as /storage/{storage_id}/sha256/{64 hex}, and the bytes come back only if they still hash to it; if they do not, the answer is 412 and nothing is served.

curl -X POST https://aisenseapi.com/services/v1/storage \
  -H "Content-Type: application/json" -d '{"result": 42}'

{ "storage_id": "123e4567-e89b-12d3-a456-426614174000",
  "storage_url": "https://aisenseapi.com/services/v1/storage/123e4567-e89b-12d3-a456-426614174000",
  "sha256_hash": "7ecbd6ed72a9632423e471e35dfa32b41e4a44b94c4e1be3a771696a73f05db4",
  "bytes": 14, "expire_timestamp": 1738457158 }

curl https://aisenseapi.com/services/v1/storage/123e4567-e89b-12d3-a456-426614174000
Response: {"result": 42}

URL Shortener REST API Endpoint

GET /url_shortener/{url}

The target URL goes inline in the path. Links expire after 24 hours.

curl "https://aisenseapi.com/services/v1/url_shortener/https://example.com/some/long/path"

{ "short_url": "https://307.fi/KtNshX2B", "expire_timestamp": 1786959715 }

Temporary DNS Name REST API Endpoint

GET /dns/{ip}

The address goes last in the path, in place of <YOUR_PUBLIC_IP>; private, reserved and documentation ranges are refused. The name is on 53for24h.com and expires after 24 hours.

curl "https://aisenseapi.com/services/v1/dns/<YOUR_PUBLIC_IP>"

{ "name": "aisense-t1mpdqk.53for24h.com", "ttl": 60, "dns_token": "shown once" }

Webhook Capture REST API Endpoint

POST /webhook_capture - GET /webhook_capture/{capture_id}

Create a capture session, point a sender at its unique URL and read back the first inbound request. The result includes method, headers, client IP and parsed body. Wait for up to 25 seconds or ask for one completion signal. No tunnel or server is needed. Expires after 24 hours.

# 1. create
curl -X POST https://aisenseapi.com/services/v1/webhook_capture
{ "ok": true, "capture_id": "6f8c9e52-...", "update_url": ".../update", "read_url": "...", "expire_timestamp": ... }

# 2. point any HTTP method at update_url

# 3. read it back
{
  "ok": true,
  "capture_id": "6f8c9e52-...",
  "captured_at_datetime": "2026-08-16T09:41:56Z",
  "request": {
    "method": "POST",
    "headers": { "content-type": "application/json" },
    "client_ip": "203.0.113.10",
    "body": { "json": { "event": "payment.created" }, "text": null, "base64": null, "raw_length": 28 }
  }
}

Webhook Action REST API EndpointAgent Optimal

POST /webhook_action - GET /webhook_action/{action_id}

Post a form definition and send the returned link to one person. Set respondents from 2 to 20 for separate one-use links and an aggregate result. Read immediately, wait for up to 25 seconds or add notify_url for one completion signal.

Field types are radio, select, text, textarea and checkbox. Group status moves through pending, partial and answered. Expires after 24 hours.

{
  "title": "Approve deployment to production?",
  "fields": [
    { "type": "radio", "name": "decision", "label": "Decision", "required": true,
      "options": [ { "value": "approve", "label": "Approve" },
                   { "value": "reject",  "label": "Reject"  } ] },
    { "type": "textarea", "name": "comment", "label": "Notes" }
  ]
}

{ "ok": true, "action_id": "9e0e6d3b-...", "form_url": ".../form", "result_url": "...",
  "expire_timestamp": ..., "expire_datetime": "2026-08-17T09:45:12Z" }
# poll the result
{ "ok": true, "action_id": "9e0e6d3b-...", "status": "answered",
  "answered_at_datetime": "2026-08-16T15:13:20Z",
  "response": { "decision": "approve", "comment": "Looks good" } }

Webhook Schedule REST API Endpoint

POST /webhook_schedule - GET /webhook_schedule/{schedule_id}

POST a URL and payload with delay_seconds or fire_at. Add every for a recurring job. Read, wait for or cancel it through the returned bearer URL. Delivery runs once a minute. Public-address checks run at creation and delivery, and redirects are not followed. Full details.

POST /webhook_schedule   { "url": "https://example.com/hook", "delay_seconds": 1200, "payload": { "job": 42 } }
  ->  { "ok": true, "schedule_id": "1f1d7b8b-...", "status": "scheduled", "result_url": "..." }

GET  /webhook_schedule/{id}
  ->  { "status": "fired", "attempts": 1, "http_status": 200 }

Agent Wake REST API EndpointAgent Optimal

POST /agent_wake - GET /agent_wake/{task_id}

Create one durable wait state for a webhook, a person or a time. The first matching event completes the task. REST clients may wait up to 25 seconds for a terminal result, and MCP clients use the Tasks extension.

POST /agent_wake   { "event_type": "webhook", "timeout_seconds": 3600 }
  ->  { "resultType": "task", "taskId": "2eb1a08d-...", "status": "working",
        "_meta": { "com.aisenseapi/agentWake": { "wakeUrl": ".../wake" } } }

GET  /agent_wake/{task_id}
  ->  { "resultType": "complete", "status": "completed", "result": { ... } }

Heartbeat REST API EndpointAgent Optimal

POST /heartbeat - POST /heartbeat/{heartbeat_id}/ping

Watch a process that should check in on a fixed rhythm. The first missed deadline fires one public webhook or wakes an Agent Wake task. A ping moves the next expected time but never moves the fixed 24-hour expiry.

POST /heartbeat
{ "expect_every_seconds": 300, "grace_seconds": 60,
  "on_miss": { "url": "https://example.com/agent-offline",
               "payload": { "agent": "worker-7" } } }

POST /heartbeat/{heartbeat_id}/ping
  -> { "status": "armed", "ping_count": 1, "next_expected_at_datetime": "..." }

The heartbeat ID is a bearer secret. Webhook destinations are checked for SSRF at creation and again at delivery. Miss actions run once with no retry. Read the Heartbeat guide.

Lease REST API EndpointAgent Optimal

POST /lease - POST /lease/complete

Let one worker claim a shared key. The winner receives an owner token and a monotonic fencing token. Other workers get HTTP 409 while it is held. A completed JSON result can be returned to later callers with the same key and fingerprint.

POST /lease/namespace   {}
  -> { "namespace": "ns_...", "entropy_bits": 256 }

POST /lease
{ "namespace": "ns_...", "key": "invoice:2026-09-05",
  "ttl_seconds": 60, "fingerprint": "charge-order-501" }
  -> { "status": "held", "owner_token": "own_...", "fencing_token": 184 }

A lease can be renewed, released or completed. The absolute lifecycle ends 24 hours after its first acquisition and cannot be extended. Read the Lease guide.

Agent Queue REST API EndpointAgent Optimal

POST /queue - POST /queue/{id}/claim

Pass JSON jobs from producers to workers with separate read, write and worker tokens.

POST /queue   {}
  -> queue_id, read_token, write_token, worker_token, expire_timestamp

POST /queue/{queue_id}/jobs
Authorization: Bearer WRITE_TOKEN
{ "job_key": "report:42", "payload": { "report_id": 42 } }

POST /queue/{queue_id}/claim
Authorization: Bearer WORKER_TOKEN
{ "visibility_timeout": 60 }

Claim returns a job with a receipt, or job: null. Use the worker token and receipt to acknowledge, release or renew. Observers read counts and jobs with the read token. Credentials belong in headers, never in URLs.

The queue and all job state expire exactly 24 hours after creation. No activity extends it. Limits are 100 distinct jobs, 16 KiB per JSON payload and five claim attempts. Jobs can be delivered again after a claim expires or is released. Queue expiry and the attempt limit may leave jobs unfinished. Initial delivery and exactly-once execution are not guaranteed. Make external actions idempotent. Read the Agent Queue guide.

Agent Inbox REST API EndpointAgent Optimal

GET /inbox - GET /inbox/{inbox_id}

Create a disposable mail address an agent can read for up to 24 hours. Verification codes and public links are extracted from the cleaned text. Attachments, raw MIME and arbitrary headers are never stored.

GET /inbox
  -> { "ok": true, "inbox_id": "a85d0bee-...", "slug": "ztjqt7n",
       "address": "aisense+ztjqt7n@aisenseapi.com" }

GET  /inbox/{inbox_id}
  -> { "received": 1, "truncated": false,
       "messages": [ { "from": "...", "codes": ["481516"], "links": ["..."] } ] }

The slug in the address is public and only lets someone send mail. The inbox_id is a bearer secret and is the only value that reads the inbox. A wrong ID and a missing inbox both answer 404. A read can wait up to 25 seconds for the next message. A full inbox, at 20 messages or 256 KiB, refuses new mail and keeps the old, which is what truncated reports. Read the Agent Inbox guide.

Crypto

Wallet generation is for development and testing only. A private key produced by a public HTTP endpoint has crossed a network you do not control. Never fund a wallet generated this way.

Solana Generate New Wallet REST API Endpoint

GET /solana/generate_new_wallet

{ "private_key": "[...]", "private_key_base58": "...", "public_address": "..." }

Bitcoin Generate New Wallet REST API Endpoint

GET /bitcoin/generate_new_wallet

Follows Bitcoin's secp256k1 standard, with the private key in hexadecimal and WIF form.

{ "private_key": "...", "private_key_wif": "...", "public_address": "..." }

Ethereum Generate New Wallet REST API Endpoint

GET /ethereum/generate_new_wallet

{ "private_key": "0x...", "public_address": "0x..." }

Solana, Bitcoin and Ethereum Balance REST API Endpoints

GET /{chain}/balance/{address}

Every chain returns both balances as strings, because Wei and lamports routinely exceed 253, the largest integer a JSON number survives in a JavaScript client, and a decimal string keeps the display unit exact too.

/solana/balance/{address}
{ "wallet": "So1111...", "balance_sol": "1694.799038633", "balance_lamports": "1694799038633" }

/bitcoin/balance/{address}
{ "wallet": "1A1zP1...", "final_balance_btc": "107.36719456", "final_balance_sats": "10736719456" }

/ethereum/balance/{address}
{ "wallet": "0xd8dA...", "balance_eth": "6.634527787345637061", "balance_wei": "6634527787345637061" }

Quick start

curl

curl https://aisenseapi.com/services/v1/uuid

Python

Zero dependencies, standard library only.

from aisense_api import AISenseAPI
api = AISenseAPI()

print(api.get_uuid()["uuid"])
print(api.hash_sha256("Hello")["sha256_hash"])
print(api.ip_reverse_lookup("8.8.8.8")["country"])

JavaScript

Node 18 or later, and every modern browser. Native fetch, no dependencies.

import { AISenseAPI } from './aisense-api.js'
const api = new AISenseAPI()

console.log((await api.getUUID()).uuid)
console.log((await api.hashSHA256('Hello')).sha256_hash)

LLM function calling

The repository includes openai-tools.json with tool definitions for any model that supports function calling, and SKILL.md for Claude.

import json
from openai import OpenAI

with open("openai-tools.json") as f:
    tools = json.load(f)

client = OpenAI()
response = client.chat.completions.create(
    model="gpt-4o", tools=tools,
    messages=[{"role": "user", "content": "Generate a UUID and hash Hello with SHA256"}]
)

Client libraries, tool definitions and tests for documented response formats: github.com/aisenseapi/aisense-free-public-rest-apis

Endpoint guides

Every endpoint has its own page with worked examples, response fields, the edge cases that matter and what the thing is actually good for.

Transform

Convert

Images

Hash

Random

Time

Web

Crypto

All endpoints

Relative to https://aisenseapi.com/services/v1. Temporary active state has a 24-hour ceiling. Heartbeat terminal state and Webhook Schedule results can remain readable for another 24 hours. Queue state shares its fixed creation-time expiry.

CategoryEndpointMethodResponse key(s)
Time/datetime[/{offset}]GETdatetime
Time/datetime/{zone}GETdatetime, timezone, abbreviation, utc_offset, dst, unixtime, raw_offset, dst_offset, dst_from, dst_until, day_of_week, day_of_year, week_number, utc_datetime
Time/ip_datetime[/{ip}]GETip, then the keys of /datetime/{zone}
Time/timestampGETtimestamp
Time/microtimestampGETmicrotimestamp
Time/timezones[/{offset}]GETtimezones
Time/swatchinternettimeGETbeat, date
Time/timestamp_convertPOSTdetected, timestamp, datetime, rfc2822, utc_datetime
Random/random_number[/{from}[/{to}]]GETrandom_number, range
Random/random_colorGETrandom_color
Random/uuidGETuuid
Random/guidGETguid
Random/password[/{length}]GETpassword, password_length
Random/passphrase[/{groups}]GETpassphrase, groups, length, entropy_bits
Transform/base64_encodePOSTbase64_encoded_data
Transform/base64_decodePOSTraw bytes, or type + decoded_data
Transform/base58_encodePOSTbase58_encoded_data
Transform/base58_decodePOSTraw bytes, or type + decoded_data
Transform/base32_encodePOSTbase32_encoded_data
Transform/base32_decodePOSTraw bytes, or type + decoded_data
Transform/hex_encodePOSThex_encoded_data
Transform/hex_decodePOSTraw bytes, or type + decoded_data
Transform/base64url_encodePOSTbase64url_encoded_data
Transform/base64url_decodePOSTraw bytes, or type + decoded_data
Transform/url_encodePOSTurl_encoded_data
Transform/url_decodePOSTurl_decoded_data
Transform/html_encodePOSThtml_encoded_data
Transform/html_decodePOSThtml_decoded_data
Transform/html_to_markdownPOSTmarkdown, title
Transform/markdown_to_htmlPOSThtml
Transform/slugifyPOSTslug
Transform/jwt_encodePOSTjwt
Transform/jwt_decodePOSTdecoded_payload
Transform/qrcode_encodePOSTqrcode_image, image_type
Transform/qrcode_decodePOSTqrcode_content
Convert/json_to_csvPOSTStorage fields, content_type, filename, operation
Convert/csv_to_jsonPOSTStorage fields, content_type, filename, operation
Convert/table_matchPOSTStorage fields, content_type, filename, operation
Convert/json_formatPOSTStorage fields, content_type, filename, operation
Convert/json_validatePOSTStorage fields, content_type, filename, operation, valid
Images/image_convertPOSTStorage fields, format, width, height, input_format, input_bytes
Images/image_compressPOSTStorage fields, format, width, height, input_format, input_bytes
Images/image_resizePOSTStorage fields, format, width, height, input_width, input_height, fit, upscaled
Images/image_metadataPOSTStorage fields, format, width, height, gps, findings
Images/image_stripPOSTStorage fields, format, width, height, input_bytes, removed, kept
Images/image_colorsPOSTStorage fields, average, dominant, count
Images/image_faviconPOSTStorage fields, files, crop, upscaled
Logic/decidePOSTanswers
Logic/mock_response/{status}[/{ms}]Anyerror or ok, with mock_response
Hash/md5_hashPOSTmd5_hash
Hash/sha1_hashPOSTsha1_hash
Hash/sha256_hashPOSTsha256_hash
Hash/sha512_hashPOSTsha512_hash
Hash/sha3_256_hashPOSTsha3_256_hash
Hash/sha3_512_hashPOSTsha3_512_hash
Hash/blake2b_hashPOSTblake2b_hash
Hash/whirlpool_hashPOSTwhirlpool_hash
Hash/blake3_hashPOSTblake3_hash
Hash/argon2id_hashPOSTargon2id_hash
Hash/bcrypt_hashPOSTbcrypt_hash
Hash/scrypt_hashPOSTscrypt_hash
Hash/password_verifyPOSTmatch, algorithm, params
Hash/crc32_checksumPOSTcrc32_checksum
Hash/hash_verifyPOSTmatch, algorithm, computed
Web/pingGETping
Web/healthGETstatus, microtimestamp
Web/client_ipGETip
Web/user_agentGETuser_agent
Web/ip_reverse_lookup/{ip}GETcountry, city, location, timezone
Web/domain_ip_lookup/{domain}GETdomain, ip
Web/email_validatePOSTvalid_syntax, has_mx, mx_hosts
Web/webhook_schedulePOST / GET / DELETEone-shot or recurring state, wait support, delivery counts
Web/agent_wakePOST / GET / DELETEtaskId, status, result
Web/heartbeatPOST / GETheartbeat_id, status, timing fields, ping_count, delivery
Web/leasePOSTstatus, owner_token, fencing_token, expiry fields, result
Web/inboxGET, or POST to createinbox_id, slug, address, received, truncated, messages
Web/queuePOST / GETqueue_id, role tokens on creation, counts and fixed expiry
Web/queue/{id}/jobs, /queue/{id}/claimPOST / GETJob payload, status, attempts and a receipt only on claim
Web/validate/{type}POSTtype, valid, per-check fields
Web/storagePOST / GETstorage_id, storage_url, sha256_hash, bytes, expire_timestamp
Web/url_shortener/{url}GETshort_url, expire_timestamp
Web/webhook_capturePOST / GETpending or captured state, update, read and wait URLs
Web/webhook_actionPOST / GETsingle or group forms, result and wait URLs
Crypto/solana/generate_new_walletGETprivate_key, private_key_base58, public_address
Crypto/solana/balance/{address}GETbalance_sol, balance_lamports
Crypto/bitcoin/generate_new_walletGETprivate_key, private_key_wif, public_address
Crypto/bitcoin/balance/{address}GETfinal_balance_btc, final_balance_sats
Crypto/ethereum/generate_new_walletGETprivate_key, public_address
Crypto/ethereum/balance/{address}GETbalance_eth, balance_wei (strings)