Skip to content

Endpoints ​

An endpoint is a route through the Manager's Enterprise Service Bus (ESB). A machine user calls a path on the Manager; the Manager authenticates the caller, optionally transforms the body with a Go template, adds backend credentials, forwards the request to your backend URL, and writes an audit row. Use endpoints when external systems or automation must reach your backends through one authenticated, audited gateway.

Endpoints belong to an application. Machine users belong to an environment.

Where endpoints live ​

Open a project, then the application, then Endpoints in the sidebar (/<project>/applications/<app>/endpoints). Any project member can view the page; creating, editing and deleting endpoints needs the project role maintainer or owner (or the system administrator role).

The list shows Name, URL (the backend target), Input Type, Output Type, Status (Enabled / Disabled) and Actions (View Details, Edit, Delete). Deleting asks for confirmation and cannot be undone.

Creating an endpoint ​

  1. Click Create Endpoint.
  2. Fill in the Create Endpoint dialog:
FieldNotes
Name (required)Up to 100 characters.
DescriptionFree text.
ESB Consume URL (required)The inbound path that selects this endpoint, e.g. /api/webhook. Must start with /, must not be an absolute URL, must not contain .. or whitespace. Up to 500 characters.
Endpoint URLThe backend address to forward to, e.g. https://backend.example.com/webhook. Must be absolute http or https with a host. Optional; up to 500 characters.
Input Message Type / Output Message TypeSOAP, XML or JSON; both can be left unset (see Message types).
Authentication TypeNone (default), Basic or Bearer. Basic shows Username and Password; Bearer shows Bearer Token. Passwords and tokens are encrypted at rest.
Log LevelNone, Basic (default) or Full. See Audit log level.
Transformation TemplateA Go text/template. See Message transformation.
Test this templateExpandable preview. Available only when editing a saved endpoint.
EnabledToggle; new endpoints default to enabled.
  1. Click Save.

The same dialog opens as Edit Endpoint from the list or from the detail page's Edit button.

The endpoint page ​

Click View Details to open /<project>/applications/<app>/endpoints/<endpointId>. Endpoint Information shows Name, Status, Description, ESB Consume URL, ESB Invocation Path (the full path callers use), Endpoint URL, Input/Output Message Type, Authentication Type, Transformation Template, Created at and Created by.

Below it, Machine Users lists which machine users may call this endpoint (see Machine user access).

Calling an endpoint ​

The ESB accepts any HTTP method at:

/esb/<applicationId><consumeURL>

For example, an endpoint with consume URL /api/webhook in application 3f2b… is called at POST /esb/3f2b…/api/webhook. The request must carry the machine user's token as Authorization: Bearer <token> (the ESB accepts Bearer tokens only), and the endpoint must be Enabled with an enabled access row for that machine user; otherwise the ESB answers 404 Endpoint not found or not enabled. Repeated failed authentications are throttled with 429 too many failed authentication attempts; retry later and a Retry-After header.

Limits (Manager config keys under esb:): request bodies are capped at max_request_bytes (default 10 MiB), upstream responses at max_response_bytes (default 10 MiB), and the forward times out after forward_timeout (default 30s).

See the ESB documentation for the full request flow and error responses.

Machine user access ​

Access is a per-(machine user, endpoint) row with its own enabled flag.

  1. On the endpoint page, click Add Machine User.
  2. Pick a Machine User and leave Enabled on.
  3. Click Add Access.

Each row in the table has an enabled toggle and a Remove Access action. Machine users are created per environment on the Machine Users page; see Machine Users.

ESB audit log level ​

Every call through an endpoint can write one ESBAuditLog row. The endpoint's Log Level decides how much:

LevelWhat is stored
NoneNothing.
Basic (default)Timestamp, endpoint, application, machine user, source IP, method, path, target URL, response status, duration, and whether a transformation was applied. No headers, no bodies.
FullEverything in Basic plus request and response headers and bodies. Sensitive headers and body fields are redacted before storage.

Database growth

Full logging stores every request and response body. Use it while debugging or where compliance requires it, then switch back to Basic.

Message transformation ​

If Transformation Template is set, the ESB parses the incoming body, renders the template with the context below, and forwards the rendered text instead of the original body. Without a template the body is forwarded unchanged.

Template context ​

  • .Data: the parsed request body (JSON object, or decoded XML/SOAP). If the body could not be parsed as JSON and no input type is set, .Data is {"Body": "<raw text>"}.
  • .Application.ID, .Application.Name, .Application.Slug, .Application.Description
  • .Endpoint.ID, .Endpoint.Name, .Endpoint.ConsumeURL, .Endpoint.URL, .Endpoint.Description
  • .User.ID, .User.Username, .User.Name: the calling machine user
  • .Meta.Timestamp (RFC 3339 string), .Meta.RequestTime (Go time.Time)
  • .Env: a map of the allow-listed environment variables PRODUCTIFY_ENV, PRODUCTIFY_REGION, APP_ENV, DEPLOYMENT_ENV. Nothing else is readable.

Template functions ​

FunctionResult
toJsonValue as a JSON string
jsonEscapeValue as a JSON string without surrounding quotes, for safe embedding inside "..."
toStringValue as a string
toUpper / toLowerUpper- or lower-case string
nowCurrent time, RFC 3339
env "KEY"The environment variable, only for the four allow-listed keys; anything else is ""

Any other function name is a template parse error.

Example ​

go
{
  "endpoint": "{{ .Endpoint.Name }}",
  "timestamp": "{{ .Meta.Timestamp }}",
  "user": "{{ jsonEscape .User.Username }}",
  "environment": "{{ .Env.PRODUCTIFY_ENV }}",
  "data": {{ .Data | toJson }}
}

Rename fields:

go
{
  "customerName": "{{ .Data.name | toUpper }}",
  "customerEmail": "{{ .Data.email | toLower }}",
  "receivedAt": "{{ now }}"
}

Convert XML to JSON: set Input Message Type to XML and Output Message Type to JSON, then:

go
{ "converted": {{ .Data | toJson }}, "processedAt": "{{ now }}" }

Testing a template ​

On a saved endpoint, open Edit Endpoint, expand Test this template, paste a Sample request body and click Run preview. The Manager renders the template on the server with the endpoint's real context and shows Rendered output and its content type. Nothing is forwarded and nothing is saved. The API equivalent is previewESBTransform(endpointId, input: { body, transformationTemplate }); transformationTemplate is optional and lets you try an unsaved candidate.

Input and output message types ​

Input Message Type controls how the body is parsed into .Data:

SettingParsing
JSONjson.Unmarshal; a parse failure is an error
XML or SOAPXML decoded to a map
unsetTry JSON; on failure .Data becomes {"Body": "<raw text>"}

Output Message Type sets the Content-Type sent to the backend when a template is applied: JSON → application/json, XML → application/xml, SOAP → text/xml; charset=utf-8, unset → application/json.

API ​

graphql
mutation {
  createEndpoint(
    applicationId: "app-uuid"
    input: {
      name: "Order webhook"
      description: "Forwards orders to the ERP"
      consumeURL: "/orders"
      url: "https://erp.example.com/api/orders"
      authType: Bearer
      authToken: "erp-token"
      inputMessageType: JSON
      outputMessageType: JSON
      logLevel: BASIC
      enabled: true
    }
  ) {
    id
    name
    consumeURL
  }
}
  • createEndpoint(applicationId: ID!, input: CreateEndpointInput!), updateEndpoint(id: ID!, input: UpdateEndpointInput!), deleteEndpoint(id: ID!). deleteEndpoint is refused once the endpoint has served logged ESB traffic: the ESB audit trail is append-only and its rows carry a NOT NULL reference to the endpoint, so the refusal names the count and points at the only remedy, updateEndpoint with enabled: false. The same applies one level up to deleteApplication, since an application whose endpoints all carry ESB rows cannot be emptied.
  • Input fields: name, description, enabled, consumeURL, url, inputMessageType / outputMessageType (SOAP | XML | JSON), authType (Basic | Bearer | None), authUsername, authPassword, authToken, transformationTemplate, logLevel (NONE | BASIC | FULL).
  • Queries: endpoint(application: ID!, id: ID!) and endpoints(application: ID!, filters, order, pagination); both need membership of the application's project (or the system administrator role).
  • Access rows: createMachineUser2Endpoint, updateMachineUser2Endpoint, deleteMachineUser2Endpoint; list with machineUser2endpoints(endpoint: ID!, ...).
  • Audit trail: esbAuditLogs(applicationId: ID!, endpointId: ID, limit: Int).

See the API Reference.

Troubleshooting ​

404 Endpoint not found or not enabled ​

The endpoint is disabled, the consume URL does not match the path after /esb/<applicationId>, or the calling machine user has no enabled access row.

Backend authentication fails ​

Check Authentication Type and the stored credential; rotate the token or password in Edit Endpoint.

Transformation errors ​

  • Check syntax and use only the functions listed above.
  • Make sure the Input Message Type matches what the caller sends; a JSON parse failure with JSON set is an error.
  • Use Test this template with a real sample body, or temporarily set Log Level to Full and read the request body from the ESB audit trail.

See also ​