---
title: What the Custom API Integration Is
description: "A **Custom API** integration lets RackHelm provision against any remote system that speaks HTTP, without anyone writing a PHP driver for it. You define where the API lives, how to authenticate, and one HTTP call per lifecycle event; RackHelm fires…"
url: "https://rackhelm.com/documentation/custom-api-overview/"
updated: "2026-09-24"
category: "Integrations: Custom API"
---

# What the Custom API Integration Is

A **Custom API** integration lets RackHelm provision against any remote system that speaks HTTP, without anyone writing a PHP driver for it. You define where the API lives, how to authenticate, and one HTTP call per lifecycle event; RackHelm fires those calls when an order is placed, suspended, renewed, cancelled or terminated. This article is for operators deciding whether a Custom API is the right tool for a given supplier.

## What it replaces

Every other integration in RackHelm — cPanel, Plesk, Pterodactyl, eNom, Namecheap and the rest — is a driver: PHP that knows one provider's quirks. A Custom API integration knows none of them. It reads a stored definition, renders your JSON template against the order, sends it, and records what happened.

That makes it the right answer whenever:

- you resell something with a modest REST API and no RackHelm driver — a licence server, a mailbox platform, a VPN provider, an in-house provisioning script;
- you have an internal system that should be told about orders, but does not need to be talked to conversationally — a fulfilment queue, a CRM, a stock ledger;
- you want a supplier notified of cancellations and renewals even though the actual provisioning is manual.

It is not the right answer when the provider needs a stateful conversation, a non-HTTP protocol, an OAuth refresh dance, or a file upload. RackHelm sends one request per event and reads one response.

## The four things a Custom API is made of

| Piece | What it holds |
| --- | --- |
| **Integration** | The connection: name, machine name, base URL, authentication, default headers, timeouts, the signing secret and the list of order variables the calls are allowed to send. |
| **Endpoints** | One HTTP call per lifecycle event — method, path, JSON payload template, query template, extra headers, what counts as success, and what to capture out of the reply. |
| **Fields** | Display rules that turn a captured value into something readable on the customer's service page — a badge, a meter, a masked licence key. |
| **Deliveries** | The log. One row per attempted call, holding the request, the reply and the outcome. |

## The events RackHelm can fire

An endpoint is bound to exactly one event. Eight of the nine are lifecycle events raised by the portal itself; the ninth, `action`, is an open-ended button.

| Event | Fired when |
| --- | --- |
| `provision` | An order item is provisioned, through the standard provisioning pipeline. This is the only event whose failure marks the service as failed. |
| `suspend` | The service is suspended (for example by the dunning run). |
| `unsuspend` | The service is unsuspended. |
| `terminate` | The service is terminated. |
| `cancellation_requested` | A customer requests cancellation, or staff mark a package pending cancellation. |
| `renew` | A renewal invoice is paid for a service that qualifies for renewal. |
| `resource_change` | An addon changes the resources on a parent service. |
| `sync` | Defined in the vocabulary, but nothing in the portal raises it yet — see the note below. |
| `action` | A named button (a "reboot" or "reissue"). Distinguished from other actions by its **Action key**. |

> **Note:** The `sync` event and customer-pressed `action` buttons are not wired to a trigger yet. The customer-facing **Refresh** and action routes exist but currently answer "not available yet". You can define endpoints for them today — they will be exercised by the **Test** tab and by a delivery replay — but nothing fires them automatically. Everything else in the table above is live.

An event with no endpoint configured does nothing at all. That is deliberate: an integration that only wants to hear about provisioning and termination is a legitimate configuration, not a half-finished one, and a missing endpoint never fails a customer's service.

## How a product is attached

An integration on its own calls nothing. You attach it to a product by opening **Catalogue → Catalogue & Groups**, editing the product, choosing **Custom API** as its integration type and picking the integration from the list. Behind the scenes the product stores the integration's id under `config['custom_api_id']` — that key is the canonical binding, and it is what every part of the feature reads.

Product addons carry their own integration, so an addon served by a Custom API gets its own events rather than riding on the parent's.

## What RackHelm guarantees about the outbound call

- **TLS verification is always on.** There is no "ignore certificate errors" option anywhere in this feature.
- **The destination is checked before every send**, not only when you saved it. Private, loopback and link-local addresses are refused, and the connection is pinned to the address that was checked.
- **Credentials never reach the log.** They are stored encrypted, excluded from the audit log, masked before a delivery row is written and masked again before it is shown.
- **Nothing outside your allowlist is interpolated.** Order variables are only sent if you named them on the **Data exposure** tab.
- **The response body has a ceiling.** A reply larger than the integration's **Max response stored** is refused rather than truncated and mis-parsed.

## Before you start

> **Warning:** Managing Custom APIs requires the `manage_custom_apis` permission, which is granted to **Super Admin only** out of the box — the Administrator role is explicitly denied it in the role seeder. This is on purpose: whoever can create a Custom API chooses the destination URL and the payload, which is both a server-side request forgery primitive and a pipe for client personal data and service credentials to a server of their choosing. Grant it per-install, deliberately, from **Users & Roles → Roles & Permissions**.

You will also need, from the supplier:

1. the base URL of their API;
2. credentials, and which scheme they use (basic, bearer, a named header, or a query parameter);
3. the path and request shape for at least a "create" call;
4. a way for them to verify a signed request, if they want one.

![The Integrations screen showing control panel cards above a Custom APIs card group](/wp-content/uploads/rackhelm-docs/integrations-customapi-integrations-screen.png)
Custom APIs live on the Integrations screen beside the control panels and registrars — there is no separate list page.

## Where to go next

- [Creating a Custom API integration](/docs/creating-a-custom-api-integration/) — the connection itself.
- [Custom API endpoints](/docs/custom-api-endpoints/) — one call per event.
- [Worked example: a licence key API](/docs/custom-api-worked-example/) — the whole thing end to end.
