Apps
Apps allow you to create custom endpoints in Aidbox. When a request is made to a custom endpoint, Aidbox proxies it to your application service.
An App is a standalone service that handles custom business logic. To enable this integration, you need to register the App resource in Aidbox, defining which endpoints should be proxied to your service and where to send the requests.
Example of App resource
To define the App, we should provide the app manifest.
PUT /App/myorg.myapp
resourceType: App
id: myorg.myapp
apiVersion: 1
type: app
endpoint:
url: https://my.service.com:8888
type: http-rpc
secret: <your-sercret>
operations: <Operations-definitions>
App manifest structure
Here's the manifest structure:
| Key | Type | Description |
|---|---|---|
| id | string | Id of the App resource |
| apiVersion (required) | integer | App API version. Currently, the only option is 1 |
| type (required) | enum | Type of application. Currently, the only option is app |
| endpoint | object | Information about endpoint: url to redirect the request, protocol, and secret |
| operations | array of operations | Custom endpoints |
| resources | array of resources in Aidbox format | Deprecated. Related resources that should be also created |
| subscriptions | array of subscriptions | Deprecated subscriptions support. Consider using Aidbox topic-based subscriptions or SubsSubscriptions instead |
endpoint
In the endpoint section, you describe how Aidbox will communicate with your service:
| Key | Type | Description |
|---|---|---|
| type (required) | string | Protocol of communication. The only option now is http-rpc |
| url (required) | string | Url of the service to redirect a request |
| secret | string | Secret for Basic Authorization header: base64(id:secret) |
operations
In the operation section, you define Custom REST operations as a map <operation-id>: <operation-definition> and access policy (which will be bound to this operation):
operations:
daily-patient-report:
method: GET
# GET /Patient/$daily-report/2024-01-01
# GET /Patient/$daily-report/2024-01-02
path: ['Patient', '$daily-report', { name: 'date'} ]
register-user:
method: POST
path: [ 'User', '$register' ]
policies:
register-user: { engine: allow }
Parameters:
| Key | Type | Description |
|---|---|---|
| method | string | One of: GET, POST, PUT, DELETE, PATCH, OPTIONS |
| path | array of strings or objects | New endpoint in Aidbox in array |
| policies | object | Access policies to create and bound to this operation |
| timeout | integer | Timeout in milliseconds; defaults to 30000. See Timeout for HTTP streaming and bundle behavior. |
resources
It is a deprecated option to create resources via Aidbox format.
In the resources section, you can provide other resources for Aidbox in the form {resourceType: {id: resource}} using Aidbox format:
resourceType: App
resources:
# resource type
AccessPolicy:
# resource id
public-policy:
# resource body
engine: allow
link:
- {id: 'opname', resourceType: 'Operation'}
In this example, the AccessPolicy resource will be created as well as the App resource.
Request Format
When Aidbox proxies a request to your service, it sends a POST request to the configured endpoint URL.
Request
type: operation
request:
resource: # request body, can be anything (null for GET)
resourceType: Parameters
parameter:
- name: patientNHSNumber
valueIdentifier:
system: https://fhir.nhs.uk/Id/nhs-number
value: "9876543210"
params: {} # Query parameters
route-params: # Path parameters from operation path
date: "2026-01-01"
headers:
content-type: application/fhir+json
authorization: Bearer <user-token>
box:
base-url: http://localhost:8080
operation:
id: getstructuredrecord
app:
id: myapp
resourceType: App
Response
Aidbox forwards your service's HTTP status code, response body, and end-to-end response headers to the client. This includes redirect and error responses. Aidbox returns redirects to the client without following them.
Aidbox preserves compressed response bytes and the Content-Encoding, Content-Length, and Content-Disposition headers. Each Set-Cookie value reaches the client as a separate header. Aidbox removes hop-by-hop headers, including Connection, Transfer-Encoding, and headers named in Connection, and manages transfer framing for the client connection. Your service can omit Content-Length when it does not know the response size in advance.
Streaming responses
For an App with endpoint.type: http-rpc, Aidbox enables response streaming by default for HTTP requests that match an operation's method and path. Aidbox sends a POST to endpoint.url with the JSON RPC envelope described above, regardless of the client's HTTP method. The envelope identifies the operation and carries the client's request data.
Aidbox forwards the body of this POST response to the original client as it reads bytes from your service, without waiting for the complete body. This applies to text and binary responses, including CSV (text/csv), NDJSON (application/x-ndjson), and server-sent events (text/event-stream). Aidbox forwards the body bytes without parsing the payload.
To deliver data before your service finishes the response, flush each portion of the body from your service. Aidbox flushes the bytes it reads to the client. For HEAD requests, Aidbox sends the response headers and omits the body.
For an App operation invoked as an entry in a transaction or batch bundle, Aidbox reads the complete response and decodes a JSON body before including the result in the bundle.
Timeout
Set operations.<operation-id>.timeout to control the timeout for that operation. The default is 30000 milliseconds.
For both HTTP streaming and calls within transaction or batch bundles, this value limits connection setup and idle socket reads while Aidbox waits for response headers or body bytes from your service. It does not limit the total duration of an active response. For SSE, send events or heartbeat comments at intervals shorter than the timeout to keep the connection active.
Cancellation and transport errors
Aidbox detects client cancellation when a write to the client fails and closes its connection to your service. While Aidbox waits for headers or body bytes from your service, the operation's idle timeout bounds cleanup of a cancelled request. Your service must handle the closed connection and stop producing the response.
If a connection failure or timeout occurs before Aidbox sends response headers to the client, Aidbox returns HTTP 500 with Content-Type: application/json. The body contains message with the transport error and endpoint with the App endpoint configuration, excluding secret.
If a transport error or idle timeout occurs after Aidbox sends response headers, Aidbox resets the client connection instead of completing the response. The client retains the status code and any body bytes it has received. Handle the interrupted response as an incomplete result.