Management API

Applications

Group endpoints by customer for multi-tenant webhook management and the Developer Portal

Applications represent your customers in Nahook. Each application groups endpoints belonging to one customer, enabling multi-tenant webhook management and access to the Developer Portal. See the Applications guide for a full walkthrough.

Response shape

FieldTypeDescription
idstringApplication ID with app_ prefix
externalIdstring | nullYour internal customer ID
namestringDisplay name
metadataobjectUp to 5 arbitrary key/value pairs
maxEndpointsinteger | nullMax endpoints this customer may have. null = unlimited (your plan limit still applies); 0 = none. Disabled endpoints still count.
showEventTypesbooleanWhether the Developer Portal shows this customer your event-type catalog. Default true.
createdAtstringISO 8601 timestamp
updatedAtstringISO 8601 timestamp

Per-customer limits and portal visibility

Two optional fields let you tailor each application to your own customer tiers. Set them when you create an application or change them later with an update.

  • maxEndpoints caps how many endpoints this customer can have. null (the default) means unlimited — bounded only by your workspace plan; 0 makes the customer read-only (they cannot create endpoints). A disabled endpoint still occupies a slot; only deleting one frees it. The cap is enforced whether the endpoint is created through the Developer Portal or the Management API — exceeding it returns 403 application_endpoint_limit_reached.
  • showEventTypes controls whether this customer sees your event-type catalog in the Developer Portal. true (the default) lets them browse events and subscribe their own endpoints; false hides the catalog and blocks new subscriptions through the portal. Existing subscriptions are untouched and keep delivering — toggling visibility never interrupts live webhooks.

Because both are per-application, you can mirror your own pricing tiers without Nahook needing to know them — for example a free customer at maxEndpoints: 3 with events hidden, and an enterprise customer with unlimited endpoints.

# Provision a free-tier customer: 3 endpoints, no event self-service
curl -X POST https://api.nahook.com/management/v1/workspaces/ws_abc/applications \
  -H "Authorization: Bearer nhm_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme Corp", "externalId": "cust_123", "maxEndpoints": 3, "showEventTypes": false}'

# Later, upgrade them: unlimited endpoints and event self-service
curl -X PATCH https://api.nahook.com/management/v1/workspaces/ws_abc/applications/app_123 \
  -H "Authorization: Bearer nhm_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"maxEndpoints": null, "showEventTypes": true}'

On update, omit a field to leave it unchanged; send maxEndpoints: null to remove the cap.


List applications

Retrieve all applications in a workspace. Supports pagination via limit and offset query parameters.

curl https://api.nahook.com/management/v1/workspaces/ws_abc/applications?limit=50&offset=0 \
  -H "Authorization: Bearer nhm_YOUR_TOKEN"
const { data } = await mgmt.applications.list("ws_abc");

for (const app of data) {
  console.log(app.name, app.externalId);
}
result = mgmt.applications.list("ws_abc")
result, err := mgmt.Applications.List(ctx, "ws_abc", nil)
var result = mgmt.applications().list("ws_abc");
var result = await mgmt.Applications.ListAsync("ws_abc");
$result = $mgmt->applications->list("ws_abc");
result = mgmt.applications.list("ws_abc")
let result = mgmt.applications().list("ws_abc", None).await?;

Create an application

Create a new application for a customer. Use externalId to link the application to your internal customer record.

curl -X POST https://api.nahook.com/management/v1/workspaces/ws_abc/applications \
  -H "Authorization: Bearer nhm_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme Corp", "externalId": "cust_123", "metadata": {"plan": "enterprise"}}'
const app = await mgmt.applications.create("ws_abc", {
  name: "Acme Corp",
  externalId: "cust_123",
  metadata: { plan: "enterprise" },
});

// app.id -> "app_..."
app = mgmt.applications.create(
    "ws_abc",
    name="Acme Corp",
    external_id="cust_123",
    metadata={"plan": "enterprise"},
)
app, err := mgmt.Applications.Create(ctx, "ws_abc", nahook.CreateApplicationOptions{
    Name:       "Acme Corp",
    ExternalID: "cust_123",
    Metadata:   map[string]string{"plan": "enterprise"},
})
var app = mgmt.applications().create(
    "ws_abc",
    new CreateApplicationOptions("Acme Corp", "cust_123", Map.of("plan", "enterprise"))
);
var app = await mgmt.Applications.CreateAsync("ws_abc", new CreateApplicationOptions
{
    Name = "Acme Corp",
    ExternalId = "cust_123",
    Metadata = new() { ["plan"] = "enterprise" },
});
$app = $mgmt->applications->create("ws_abc", [
    "name" => "Acme Corp",
    "externalId" => "cust_123",
    "metadata" => ["plan" => "enterprise"],
]);
app = mgmt.applications.create(
  "ws_abc",
  name: "Acme Corp",
  external_id: "cust_123",
  metadata: { "plan" => "enterprise" },
)
let app = mgmt.applications().create(
    "ws_abc",
    CreateApplicationOptions {
        name: "Acme Corp".into(),
        external_id: Some("cust_123".into()),
        metadata: Some(HashMap::from([("plan".into(), "enterprise".into())])),
    },
).await?;

Get an application

Retrieve a single application by ID.

curl https://api.nahook.com/management/v1/workspaces/ws_abc/applications/app_123 \
  -H "Authorization: Bearer nhm_YOUR_TOKEN"
const app = await mgmt.applications.get("ws_abc", "app_123");
app = mgmt.applications.get("ws_abc", "app_123")
app, err := mgmt.Applications.Get(ctx, "ws_abc", "app_123")
var app = mgmt.applications().get("ws_abc", "app_123");
var app = await mgmt.Applications.GetAsync("ws_abc", "app_123");
$app = $mgmt->applications->get("ws_abc", "app_123");
app = mgmt.applications.get("ws_abc", "app_123")
let app = mgmt.applications().get("ws_abc", "app_123").await?;

Update an application

Update application properties. Only the fields you provide will be changed.

curl -X PATCH https://api.nahook.com/management/v1/workspaces/ws_abc/applications/app_123 \
  -H "Authorization: Bearer nhm_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme Corporation"}'
const app = await mgmt.applications.update("ws_abc", "app_123", {
  name: "Acme Corporation",
});
app = mgmt.applications.update("ws_abc", "app_123", name="Acme Corporation")
app, err := mgmt.Applications.Update(ctx, "ws_abc", "app_123", nahook.UpdateApplicationOptions{
    Name: stringPtr("Acme Corporation"),
})
var app = mgmt.applications().update(
    "ws_abc",
    "app_123",
    new UpdateApplicationOptions("Acme Corporation", null)
);
var app = await mgmt.Applications.UpdateAsync("ws_abc", "app_123", new UpdateApplicationOptions
{
    Name = "Acme Corporation",
});
$app = $mgmt->applications->update("ws_abc", "app_123", [
    "name" => "Acme Corporation",
]);
app = mgmt.applications.update("ws_abc", "app_123", name: "Acme Corporation")
let app = mgmt.applications().update(
    "ws_abc",
    "app_123",
    UpdateApplicationOptions {
        name: Some("Acme Corporation".into()),
        metadata: None,
    },
).await?;

Delete an application

Permanently delete an application.

Deleting an application removes all endpoints and portal sessions associated with it.

curl -X DELETE https://api.nahook.com/management/v1/workspaces/ws_abc/applications/app_123 \
  -H "Authorization: Bearer nhm_YOUR_TOKEN"
await mgmt.applications.delete("ws_abc", "app_123");
mgmt.applications.delete("ws_abc", "app_123")
err := mgmt.Applications.Delete(ctx, "ws_abc", "app_123")
mgmt.applications().delete("ws_abc", "app_123");
await mgmt.Applications.DeleteAsync("ws_abc", "app_123");
$mgmt->applications->delete("ws_abc", "app_123");
mgmt.applications.delete("ws_abc", "app_123")
mgmt.applications().delete("ws_abc", "app_123").await?;

Application Endpoints

Applications can have their own endpoints. These are regular endpoints but scoped to a specific application for multi-tenant isolation.

List application endpoints

curl https://api.nahook.com/management/v1/workspaces/ws_abc/applications/app_123/endpoints \
  -H "Authorization: Bearer nhm_YOUR_TOKEN"
const { data } = await mgmt.applications.listEndpoints("ws_abc", "app_123");
result = mgmt.applications.list_endpoints("ws_abc", "app_123")
result, err := mgmt.Applications.ListEndpoints(ctx, "ws_abc", "app_123")
var result = mgmt.applications().listEndpoints("ws_abc", "app_123");
var result = await mgmt.Applications.ListEndpointsAsync("ws_abc", "app_123");
$result = $mgmt->applications->listEndpoints("ws_abc", "app_123");
result = mgmt.applications.list_endpoints("ws_abc", "app_123")
let result = mgmt.applications().list_endpoints("ws_abc", "app_123").await?;

Create an application endpoint

curl -X POST https://api.nahook.com/management/v1/workspaces/ws_abc/applications/app_123/endpoints \
  -H "Authorization: Bearer nhm_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://acme.com/webhooks"}'
const ep = await mgmt.applications.createEndpoint("ws_abc", "app_123", {
  url: "https://acme.com/webhooks",
});
ep = mgmt.applications.create_endpoint(
    "ws_abc",
    "app_123",
    url="https://acme.com/webhooks",
)
ep, err := mgmt.Applications.CreateEndpoint(ctx, "ws_abc", "app_123", nahook.CreateEndpointOptions{
    URL: "https://acme.com/webhooks",
})
var ep = mgmt.applications().createEndpoint(
    "ws_abc",
    "app_123",
    CreateEndpointOptions.builder("https://acme.com/webhooks").build()
);
var ep = await mgmt.Applications.CreateEndpointAsync("ws_abc", "app_123", new CreateEndpointOptions
{
    Url = "https://acme.com/webhooks",
});
$ep = $mgmt->applications->createEndpoint("ws_abc", "app_123", [
    "url" => "https://acme.com/webhooks",
]);
ep = mgmt.applications.create_endpoint(
  "ws_abc",
  "app_123",
  url: "https://acme.com/webhooks",
)
let ep = mgmt.applications().create_endpoint(
    "ws_abc",
    "app_123",
    CreateEndpointOptions {
        url: "https://acme.com/webhooks".into(),
        endpoint_type: None,
        description: None,
        metadata: None,
        config: None,
        auth_username: None,
        auth_password: None,
    },
).await?;