Authorization header). Many routes use an organization ID in the path — see Organization ID for where to find it.
This guide is a minimal walkthrough for creating core Pangolin components (sites, resources, targets) via the API. It is not exhaustive — some elements are omitted for simplicity — but everything shown here works and illustrates patterns used elsewhere in the API. For full coverage of endpoints (get, update, delete, list, etc.), use the Swagger docs.
What is an identifier?
In the Pangolin app, sites, public resources, private resources, and clients have an Identifier. In the API, this value is calledniceId.
The identifier is a human-readable, organization-unique value you can use when you want something more stable and memorable than a numeric ID. For example, a site might have a numeric siteId like 8723 and a niceId like warehouse-west.
Identifiers are especially useful for automation:
- In Blueprints, resource and site keys act as stable identifiers. A target can reference a site by its identifier, such as
site: warehouse-west. - In the API, responses include both the numeric ID and
niceIdwhen the object supports identifiers. Some routes can also look up objects byniceId, such asGET /org/{orgId}/site/{niceId}for sites.
siteId, resourceId, or siteResourceId. Use niceId when an endpoint or blueprint field asks for an identifier.
Create site
This section assumes you’re creating a Newt site. For all Site endpoints, see Site API (Swagger). PUT/org/{orgId}/site
Path
orgId(string) — organization ID
Example Response
Advanced option: pick-site-defaults
Use this when you want to generate some template values and control the site creation. GET/org/{orgId}/pick-site-defaults
Returns values you pass into the create-site endpoint.
Path
orgId(string) — organization ID
Create site
PUT/org/{orgId}/site
Path
orgId(string) — organization ID
Example Response
Create public HTTP resource
You need a domain ID before creating a resource. List your org’s domains, then create the resource with the chosen domain. For all Resource endpoints, see Resource API (Swagger).1
List domains
Call the list-domains endpoint to get available domains and their
domainId values.2
Create the resource
Call the create-resource endpoint with
http: true and the domainId from step 1.3
Add targets to the resource
Call the create-target endpoint for each backend (site + ip:port) that should serve traffic for the resource.
List domains
GET/org/{orgId}/domains
Returns all domains for the organization. Use domainId from a domain when creating a resource.
Path
orgId(string) — organization ID
Example Response
Create public HTTP resource
PUT/org/{orgId}/resource
Path
orgId(string) — organization ID
Subdomain and domain types
Domains come in three types: ns | cname | wildcard.
Wildcard is only available in self-hosted Pangolin. Pangolin Cloud uses ns and cname only.
- ns — You can use the base domain (set
subdomaintonull) or set a subdomain (e.g.my-app→my-app.digpangolin.io). - cname — Only the base domain is used; set
subdomaintonull(the domain’sbaseDomainis the FQDN). - wildcard — Same as ns for subdomain behavior (self-hosted only).
subdomain value is combined with the base domain from domainId to form the FQDN. Omit subdomain or pass null when using the base domain alone.
Example request
Add targets to the resource
PUT/resource/{resourceId}/target
Add a target (backend) to a resource. Use the numeric resourceId from the create-resource response. The target is the site and address (ip + port) that will receive traffic for the resource. For all Target endpoints, see Target API (Swagger).
Path
resourceId(number) — From create-resource response (e.g.9943)
Example request
Create private resource
In the API Private Resources are called site resources. You need an existing site. For more endpoints, see API docs (Swagger).Create site resource
PUT/org/{orgId}/site-resource
Path
orgId(string) — organization ID
TCP/UDP port range strings: Control which ports are allowed for the private resource.
"*"— Allow all ports (common for TCP when you want full access to the host).""(empty string) — Allow no ports. Use when you don’t need that protocol (e.g.udpPortRangeString: ""if only TCP is used).- Specific ports or ranges — Comma-separated list: single ports (e.g.
"80,443") or ranges (e.g."8000-9000"). Example:"80,443,8080-8090"allows 80, 443, and 8080–8090.
tcpPortRangeString and udpPortRangeString independently (e.g. TCP all, UDP none, or vice versa).
If you omit roleIds/userIds, the org admin role is granted access by default. Add IDs to restrict access.
Example request
Assign users and roles to a resource (public or private)
You can grant access to a public resource or a private (site) resource by adding roles or users. First list roles and users in the org to get IDs, then call the add endpoints. The Admin role cannot be assigned via these endpoints.Get role and user IDs
GET/org/{orgId}/roles — Returns roles in the org. Use roleId (number) when adding a role to a resource. Query: limit, offset (optional).
GET /org/{orgId}/users — Returns users in the org. Use id (string) as userId when adding a user to a resource. Query: limit, offset (optional).
Public resource (HTTP/resources)
POST/resource/{resourceId}/roles/add — Path: resourceId (number, from create-resource). Body: { "roleId": number }. Admin role not allowed.
POST /resource/{resourceId}/users/add — Path: resourceId (number). Body: { "userId": string }.
Both return { "data": {}, "success": true, "error": false, "message": "...", "status": 201 }.
Private resource (site resource)
POST/site-resource/{siteResourceId}/roles/add — Path: siteResourceId (number, from create site-resource). Body: { "roleId": number }. Admin role not allowed.
POST /site-resource/{siteResourceId}/users/add — Path: siteResourceId (number). Body: { "userId": string }.
Same response shape as above. Role must belong to the same org as the site resource. For more endpoints (list/remove), see Resource API.
