Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: FluentEDI Data API
version: 1.1.0
summary: Deterministic tools for AI agents. No key, no signup, no SDK.
description: 'A public HTTP API of deterministic tools for the work a language model cannot do reliably by reasoning: knowing the current time in any timezone and whether an instant falls inside a window, exact arithmetic, hashing and signature verification, canonicalizing and content-addressing JSON, repairing malformed JSON and pinpointing where it broke, querying and diffing structured data, parsing CSV correctly, converting units, colours and currencies at live ECB rates, testing regular expressions…'
license:
name: Free to use
identifier: MIT
servers:
- url: https://fluentedi.com
tags:
- name: Data
description: JSON and tabular data
paths:
/v1/json/query:
get:
operationId: json_query_get
summary: Extract values from a JSON document with a JSONPath expression
description: Runs a JSONPath query and returns the matching values with their concrete paths. Supports property access, array indexing (including negative indices), slices, wildcards, recursive descent (`..`) and filters (`[?(@.price > 10)]`). Pull three fields out of a large API response without carrying the whole document through context.
tags:
- Data
parameters:
- name: json
in: query
required: true
description: The JSON document, as an object or a JSON string.
schema:
description: The JSON document, as an object or a JSON string.
maxLength: 1000000
- name: path
in: query
required: true
description: JSONPath expression, e.g. "$.items[*].id" or "$..author".
schema:
description: JSONPath expression, e.g. "$.items[*].id" or "$..author".
type: string
maxLength: 1000
examples:
- $.items[*].id
- name: first_only
in: query
required: false
description: Return only the first match.
schema:
description: Return only the first match.
type: boolean
default: false
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.
post:
operationId: json_query_post
summary: Extract values from a JSON document with a JSONPath expression
description: Runs a JSONPath query and returns the matching values with their concrete paths. Supports property access, array indexing (including negative indices), slices, wildcards, recursive descent (`..`) and filters (`[?(@.price > 10)]`). Pull three fields out of a large API response without carrying the whole document through context.
tags:
- Data
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
json:
description: The JSON document, as an object or a JSON string.
maxLength: 1000000
path:
description: JSONPath expression, e.g. "$.items[*].id" or "$..author".
type: string
maxLength: 1000
examples:
- $.items[*].id
first_only:
description: Return only the first match.
type: boolean
default: false
required:
- json
- path
additionalProperties: false
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.
/v1/json/repair:
get:
operationId: json_repair_get
summary: Repair malformed JSON and pinpoint the exact line and column when it cannot be…
description: 'Takes JSON that almost parses and makes it parse: markdown code fences, prose wrapped around the object, trailing commas, single or smart quotes, unquoted keys, Python True/False/None, comments, NaN, and brackets left open by a truncated response. Every change is reported, so the caller learns what its generator got wrong rather than silently depending on a fixer. When the input cannot be salvaged it returns the precise line, column and a caret pointing at the offending character — which is what makes the next attempt succeed instead of guessing.'
tags:
- Data
parameters:
- name: input
in: query
required: true
description: The malformed JSON text.
schema:
description: The malformed JSON text.
type: string
maxLength: 1000000
- name: close_truncated
in: query
required: false
description: Close brackets left open by a cut-off response.
schema:
description: Close brackets left open by a cut-off response.
type: boolean
default: true
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.
post:
operationId: json_repair_post
summary: Repair malformed JSON and pinpoint the exact line and column when it cannot be…
description: 'Takes JSON that almost parses and makes it parse: markdown code fences, prose wrapped around the object, trailing commas, single or smart quotes, unquoted keys, Python True/False/None, comments, NaN, and brackets left open by a truncated response. Every change is reported, so the caller learns what its generator got wrong rather than silently depending on a fixer. When the input cannot be salvaged it returns the precise line, column and a caret pointing at the offending character — which is what makes the next attempt succeed instead of guessing.'
tags:
- Data
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
input:
description: The malformed JSON text.
type: string
maxLength: 1000000
close_truncated:
description: Close brackets left open by a cut-off response.
type: boolean
default: true
required:
- input
additionalProperties: false
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.
/v1/json/canonical:
get:
operationId: json_canonical_get
summary: Canonicalize JSON (RFC 8785) and content-address it with SHA-256 and a CIDv1
description: 'Serializes a JSON document to its one canonical form — keys sorted, whitespace dropped, numbers in ECMAScript form — then hashes it. Two documents that mean the same thing produce the same digest regardless of key order or formatting, which is what makes the digest quotable as a receipt. A log line is a claim that the process which wrote it could also edit; a content address is computed from the content, so changing the content changes the address. Pair it with crypto.verify: canonicalize, sign the digest with your own key, and anyone can check the pair without trusting either of you.'
tags:
- Data
parameters:
- name: json
in: query
required: true
description: The JSON document, as an object or a JSON string.
schema:
description: The JSON document, as an object or a JSON string.
maxLength: 1000000
- name: include_canonical
in: query
required: false
description: Include the canonical serialization itself, not just its digest.
schema:
description: Include the canonical serialization itself, not just its digest.
type: boolean
default: true
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.
post:
operationId: json_canonical_post
summary: Canonicalize JSON (RFC 8785) and content-address it with SHA-256 and a CIDv1
description: 'Serializes a JSON document to its one canonical form — keys sorted, whitespace dropped, numbers in ECMAScript form — then hashes it. Two documents that mean the same thing produce the same digest regardless of key order or formatting, which is what makes the digest quotable as a receipt. A log line is a claim that the process which wrote it could also edit; a content address is computed from the content, so changing the content changes the address. Pair it with crypto.verify: canonicalize, sign the digest with your own key, and anyone can check the pair without trusting either of you.'
tags:
- Data
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
json:
description: The JSON document, as an object or a JSON string.
maxLength: 1000000
include_canonical:
description: Include the canonical serialization itself, not just its digest.
type: boolean
default: true
required:
- json
additionalProperties: false
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.
/v1/json/diff:
get:
operationId: json_diff_get
summary: Structural difference between two JSON documents, as RFC 6902-style operations
description: Compares two JSON documents key by key and reports every addition, removal and change with a JSON Pointer path. Key order and formatting are ignored, so it answers 'did the data actually change' rather than 'did the bytes change' — the right check for API responses and config drift.
tags:
- Data
parameters:
- name: a
in: query
required: true
description: First document (object or JSON string).
schema:
description: First document (object or JSON string).
maxLength: 1000000
- name: b
in: query
required: true
description: Second document (object or JSON string).
schema:
description: Second document (object or JSON string).
maxLength: 1000000
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.
post:
operationId: json_diff_post
summary: Structural difference between two JSON documents, as RFC 6902-style operations
description: Compares two JSON documents key by key and reports every addition, removal and change with a JSON Pointer path. Key order and formatting are ignored, so it answers 'did the data actually change' rather than 'did the bytes change' — the right check for API responses and config drift.
tags:
- Data
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
a:
description: First document (object or JSON string).
maxLength: 1000000
b:
description: Second document (object or JSON string).
maxLength: 1000000
required:
- a
- b
additionalProperties: false
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.
/v1/json/schema:
get:
operationId: json_schema_get
summary: Infer a JSON Schema from an example document
description: Generates a draft 2020-12 JSON Schema from one or more sample documents, detecting string formats (date-time, email, uri, uuid, ipv4) and merging array members into a single item schema. Turns an undocumented API response into a contract you can validate against or hand to a typed client generator.
tags:
- Data
parameters:
- name: json
in: query
required: true
description: Sample document, or an array of samples to merge.
schema:
description: Sample document, or an array of samples to merge.
maxLength: 1000000
- name: title
in: query
required: false
description: Optional schema title.
schema:
description: Optional schema title.
type: string
default: ''
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.
post:
operationId: json_schema_post
summary: Infer a JSON Schema from an example document
description: Generates a draft 2020-12 JSON Schema from one or more sample documents, detecting string formats (date-time, email, uri, uuid, ipv4) and merging array members into a single item schema. Turns an undocumented API response into a contract you can validate against or hand to a typed client generator.
tags:
- Data
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
json:
description: Sample document, or an array of samples to merge.
maxLength: 1000000
title:
description: Optional schema title.
type: string
default: ''
required:
- json
additionalProperties: false
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.
/v1/api/diff:
get:
operationId: api_diff_get
summary: Diff an API's declared contract against payloads it actually returned; classify…
description: 'Answers ''is this endpoint keeping its promise'' — the failure mode where docs say one thing and the live API returns another, the schema validates, and nothing errors. Give it the declared JSON Schema (or a baseline payload to infer one from) plus one or more observed payloads. Returns a verdict, the inferred observed schema, and classified findings: type_mismatch, missing_field and enum_violation (action: block), nullable_in_practice, format_mismatch, undeclared_field and extra_field (action: warn), each with a JSON Pointer path and how many samples it affected. Declared-schema keywords outside the checked subset are listed in ignored_keywords, never silently trusted. Stateless: you hold the baseline, nothing is stored.'
tags:
- Data
parameters:
- name: declared
in: query
required: false
description: 'Declared contract: a JSON Schema (object or string). Omit to infer one from `baseline`.'
schema:
description: 'Declared contract: a JSON Schema (object or string). Omit to infer one from `baseline`.'
maxLength: 500000
- name: baseline
in: query
required: false
description: 'Alternative to `declared`: a known-good payload (or array of them) to infer the contract from.'
schema:
description: 'Alternative to `declared`: a known-good payload (or array of them) to infer the contract from.'
maxLength: 500000
- name: observed
in: query
required: true
description: Payload the endpoint actually returned, or an array of payloads to check together.
schema:
description: Payload the endpoint actually returned, or an array of payloads to check together.
maxLength: 1000000
- name: samples
in: query
required: false
description: Treat a top-level `observed` array as multiple samples rather than one array payload.
schema:
description: Treat a top-level `observed` array as multiple samples rather than one array payload.
type: boolean
default: true
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.
post:
operationId: api_diff_post
summary: Diff an API's declared contract against payloads it actually returned; classify…
description: 'Answers ''is this endpoint keeping its promise'' — the failure mode where docs say one thing and the live API returns another, the schema validates, and nothing errors. Give it the declared JSON Schema (or a baseline payload to infer one from) plus one or more observed payloads. Returns a verdict, the inferred observed schema, and classified findings: type_mismatch, missing_field and enum_violation (action: block), nullable_in_practice, format_mismatch, undeclared_field and extra_field (action: warn), each with a JSON Pointer path and how many samples it affected. Declared-schema keywords outside the checked subset are listed in ignored_keywords, never silently trusted. Stateless: you hold the baseline, nothing is stored.'
tags:
- Data
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
declared:
description: 'Declared contract: a JSON Schema (object or string). Omit to infer one from `baseline`.'
maxLength: 500000
baseline:
description: 'Alternative to `declared`: a known-good payload (or array of them) to infer the contract from.'
maxLength: 500000
observed:
description: Payload the endpoint actually returned, or an array of payloads to check together.
maxLength: 1000000
samples:
description: Treat a top-level `observed` array as multiple samples rather than one array payload.
type: boolean
default: true
required:
- observed
additionalProperties: false
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.
/v1/csv/convert:
get:
operationId: csv_convert_get
summary: Convert between CSV and JSON with correct quote handling
description: 'A full RFC 4180 parser: quoted fields, escaped quotes, embedded commas and newlines inside cells all survive the round trip, and the delimiter is detected automatically. Splitting CSV on commas is the classic silent data-corruption bug; this does not have it.'
tags:
- Data
parameters:
- name: input
in: query
required: true
description: CSV text, or JSON array of objects when converting to CSV.
schema:
description: CSV text, or JSON array of objects when converting to CSV.
maxLength: 1000000
- name: direction
in: query
required: false
description: Conversion direction.
schema:
description: Conversion direction.
type: string
enum:
- csv_to_json
- json_to_csv
default: csv_to_json
- name: delimiter
in: query
required: false
description: Field delimiter. "auto" detects among comma, semicolon, tab and pipe.
schema:
description: Field delimiter. "auto" detects among comma, semicolon, tab and pipe.
type: string
default: auto
maxLength: 4
- name: header
in: query
required: false
description: Treat the first CSV row as column names.
schema:
description: Treat the first CSV row as column names.
type: boolean
default: true
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.
post:
operationId: csv_convert_post
summary: Convert between CSV and JSON with correct quote handling
description: 'A full RFC 4180 parser: quoted fields, escaped quotes, embedded commas and newlines inside cells all survive the round trip, and the delimiter is detected automatically. Splitting CSV on commas is the classic silent data-corruption bug; this does not have it.'
tags:
- Data
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
input:
description: CSV text, or JSON array of objects when converting to CSV.
maxLength: 1000000
direction:
description: Conversion direction.
type: string
enum:
- csv_to_json
- json_to_csv
default: csv_to_json
delimiter:
description: Field delimiter. "auto" detects among comma, semicolon, tab and pipe.
type: string
default: auto
maxLength: 4
header:
description: Treat the first CSV row as column names.
type: boolean
default: true
required:
- input
additionalProperties: false
responses:
'200':
description: Tool result.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
tool:
type: string
result:
type: object
description: Tool-specific result payload.
'400':
description: Invalid input. The body carries the parameter schema and working examples.