Skip to main content

AI Message Mappers

A Message Mapper reshapes the JSON payload flowing through one operation of a published API — in one direction only. It exists to bridge the gap between how you want an agent to send/receive data and how the upstream API actually expects it, without asking the upstream to change.

  • direction: "request" — reshapes what the caller (agent) sends into what the upstream API actually expects.
  • direction: "response" — reshapes what the upstream API returns into what the caller expects.

Each mapper applies to exactly one OpenAPI operationId, in exactly one direction — you can't have two request mappers (or two response mappers) for the same operation; edit the existing one instead.


Design-time AI, runtime determinism​

This is the important safety property: the AI is only ever used at save time, to propose a transform_spec from a sample pair you provide. Once saved, every real request runs that expression through a deterministic, sandboxed evaluator (the same safe_eval engine Agent Builder's own transform node uses) — never a live LLM call on the request hot path.

transform_spec is a single Python-expression string, evaluated with one bound name, input (the payload being reshaped):

{"petName": input["name"], "petAge": input["age"]}

The evaluator only permits:

  • Dict and list literals
  • Indexing/subscripting (input["key"], input["list"][0])
  • Arithmetic, comparison, and boolean operators, and ternary expressions
  • A fixed whitelist of built-ins: abs, len, max, min, round, sum, any, all, zip, enumerate, map, filter, sorted, reversed, list, dict, set, tuple, bool, int, str, float

It does not permit attribute or method calls (no .upper(), no .strip()), imports, comprehensions, lambdas, function/class definitions, or any name other than input.


Endpoints​

All under /api/v1/api-definitions/{api_definition_id}:

EndpointDescription
GET /mappersList all message mappers for this API
POST /mappersCreate a mapper — operation_id, direction, optional source_sample/target_sample/transform_spec, enabled, test_cases
GET /mappers/{mapper_id}Get one mapper
PUT /mappers/{mapper_id}Update a mapper (partial — only provided fields change)
DELETE /mappers/{mapper_id}Delete a mapper
POST /mappers/generateAI-assisted: propose a transform_spec from a source_sample/target_sample pair. Doesn't save anything — review and save the proposal like any other field.
POST /mappers/{mapper_id}/testRun the mapper's transform_spec against its saved test_cases and record pass/fail

Creating, editing, or deleting a mapper requires the api_developer, lifecycle_manager, space_admin, or admin role on the parent API (see Catalogs, Spaces & Roles).

Generating a mapper​

POST /mappers/generate
{
  "operation_id": "createPet",
  "direction": "request",
  "source_sample": { "name": "Rex", "age": 3 },
  "target_sample": { "petName": "Rex", "petAge": 3 }
}
{ "transform_spec": "{\"petName\": input[\"name\"], \"petAge\": input[\"age\"]}", "warning": null }

If the LLM call itself fails (no default model configured, provider error), you get a 502 telling you to configure a default model or write the expression by hand — mapper generation isn't scoped to any API Space's own LLM config (API Spaces intentionally carry none), it always uses the instance-wide default model.

The proposal is also dry-run against your source_sample before being returned, so an obviously broken expression is flagged immediately rather than at test time.

Testing a mapper​

POST /mappers/{mapper_id}/test
{
  "all_passed": true,
  "results": [
    { "index": 0, "passed": true, "actual_output": {"petName": "Rex", "petAge": 3}, "expected_output": {"petName": "Rex", "petAge": 3} }
  ]
}

Each entry in test_cases is {"input": ..., "expected_output": ...}. The mapper needs both a saved transform_spec and at least one test case, or the endpoint returns a 400. The pass/fail result is cached on the mapper (last_test_passed, last_tested_at) so the builder UI can show status without re-running the test on every page load.


Taking effect​

A mapper runs whenever its parent API is called through the API Gateway, which every published API goes through. If the parent API is already published, adding/editing/deleting a mapper takes effect on the next call — no need to unpublish and republish.

Because that change goes live immediately, changing a mapper on a published API needs a lifecycle_manager, space_admin or admin. An api_developer pulls the API back to draft first, so the change goes through review like any other edit.

transform_spec is syntax-checked when you save, so a typo is rejected with a 422 instead of failing every live call through that operation. If a mapper still fails at call time (for example, a field missing from a real response), the gateway returns 502 request_mapping_failed or response_mapping_failed; the full error is in the server log under the response's reference.


  • AI Protocol Mappers — the other half of the pipeline, for wire-format conversion (XML/SOAP/form) rather than JSON reshaping
  • API Gateway — the exact order mappers run in on a real request
  • Tool Server Publishing — why having an enabled mapper changes which URL gets registered
Hrida.ai is proprietary software of Zlabs Innovation. See the license for terms. © 2026 Zlabs Innovation.