Application Connections API
Use these routes to read an organization's visible resources, create and remove private connections between applications, and save map card positions. The layout is independent and does not change connections, permissions, or resource settings.
Authentication and authorization
These routes require a valid user session. API keys are not accepted and return 401. Select the active organization: the x-organization-id header must match the organization ID in the route.
Authorization: Bearer <user-token>
x-organization-id: <organization-id>
Content-Type: application/jsonTo read the map, the user must be able to view the organization's resources. Creating or removing a connection requires two permissions:
| Permission | Where |
|---|---|
project.connections.outgoing.update | Source application |
project.connections.incoming.update | Target application |
The organization owner has all permissions. Responses describe only resources the user can view and do not include credentials or implementation details.
Base URL and routes
https://api.zenifra.com/v1| Purpose | Method and route |
|---|---|
| Read resources and connections | GET /organizations/:id/connections |
| Create a connection | PUT /organizations/:id/connections/:sourceId/:targetId |
| Remove a connection | DELETE /organizations/:id/connections/:sourceId/:targetId |
| Read the map layout | GET /organizations/:id/connection-layout |
| Save the map layout | PUT /organizations/:id/connection-layout |
Read the map
GET /v1/organizations/:id/connectionsThe response uses the { "data": ... } envelope and contains nodes (visible resources) and connections (connections between applications).
{
"data": {
"nodes": [
{
"id": "<application-id>",
"name": "Checkout API",
"kind": "application",
"status": "<resource-status>",
"eligible": true,
"sourceEligible": true,
"targetEligible": true,
"internalHostname": "checkout-api.6a11bedda78ad3108eb20e2c.zenifra.local"
},
{
"id": "<another-application-id>",
"name": "Orders worker",
"kind": "application",
"status": "<resource-status>",
"eligible": true,
"sourceEligible": true,
"targetEligible": true
},
{
"id": "<database-id>",
"name": "Orders PostgreSQL database",
"kind": "database",
"status": "<resource-status>",
"eligible": false,
"sourceEligible": false,
"targetEligible": false,
"reason": "<reason>"
}
],
"connections": [
{
"id": "<connection-id>",
"sourceId": "<another-application-id>",
"targetId": "<application-id>",
"status": "active"
}
]
}
}Resources (nodes)
| Field | Description |
|---|---|
id, name, status | Identification and current state of the resource. |
kind | Resource family, such as application, database, or managed_service. |
eligible | Whether the resource can take part in connections. |
sourceEligible | Whether the resource can be a source. |
targetEligible | Whether the resource can be a target. |
reason | Reason, when the resource is not eligible. |
internalHostname | The project's internal address. Present after the project becomes the target of a connection for the first time, and stays afterward. |
Connections (connections)
| Field | Description |
|---|---|
id | Connection identifier. |
sourceId | Source application (the caller). |
targetId | Target application (the receiver). |
status | preparing, active, removing, or failed. |
failedAction | connect or disconnect. Present only when status is failed. |
A failed connection means the last operation did not complete. Repeat the same call (PUT if failedAction is connect, DELETE if it is disconnect) to try again.
Create a connection
PUT /v1/organizations/:id/connections/:sourceId/:targetIdThe request has no body. The connection applies only from sourceId to targetId; to allow the opposite direction, create another connection. The source calls the target at http://<project>.<organization-id>.zenifra.local, over HTTP on the default port; this call travels only inside the organization's private network, and public traffic stays on HTTPS. The address uses the organization identifier (24 hexadecimal characters) to be unique, and it does not change if the project or the organization is renamed.
| Status | Meaning |
|---|---|
201 | Connection created. |
200 | The connection was already active. |
The response contains { "status": "success", "data": <connection> }, with the connection in the same shape as an item of connections.
{
"status": "success",
"data": {
"id": "<connection-id>",
"sourceId": "<another-application-id>",
"targetId": "<application-id>",
"status": "active"
}
}The source application may be restarted to apply the change. The address is available on every instance of it once the restart finishes.
Remove a connection
DELETE /v1/organizations/:id/connections/:sourceId/:targetIdReturns 204 and is idempotent: removing a connection that does not exist also returns 204. New connections for the pair are blocked immediately. Connections that are already open are not cut by the disconnection itself, but they may end if the source application is restarted to apply the change.
Errors
| Status | When |
|---|---|
401 | Missing or invalid session. API keys are not accepted on these routes. |
403 | No permission on the source, the target, or to read the organization. |
409 | The target is not ready yet, or an operation is already in progress for the pair. |
422 | The source or target is not eligible, for example because it is not an HTTP application in the organization or is a preview. |
502 | The operation failed. The connection is left with status: "failed" and can be tried again. |
On a 409 for an operation in progress or a target that is not ready, wait and repeat the call. Error messages are sanitized and do not expose implementation details.
Read and save the layout
GET /v1/organizations/:id/connection-layoutThe layout is per user and organization and has the following shape:
{
"data": {
"positions": [
{ "projectId": "<resource-id>", "x": 160, "y": 80 },
{ "projectId": "<another-resource-id>", "x": 520, "y": 80 }
]
}
}Save positions with PUT /v1/organizations/:id/connection-layout, sending { "positions": [...] }. Each item contains projectId, x, and y. The list can contain up to 5,000 positions; coordinates must be finite numbers between -100000 and 100000, and each ID must belong to a resource the user can view in that organization.
Moving a card changes only that layout. This operation does not create or remove connections.
Next steps
- Read the internal connections guide.
- See the API overview.
- Review organization access rules.
Last updated on