Skip to main content
Each member of an organization gets one OpenVPN client profile. A single endpoint both issues and returns it:
The first call generates the certificate on the VPN host and consumes one licence. Every later call returns the same certificate and consumes nothing, so the endpoint is safe to call repeatedly.

Prerequisites

Before a certificate can be issued:
  • You are an active member of the organization.
  • A VPN configuration is assigned to that organization.
  • That VPN’s commands map defines a create_cert entry.
  • The organization has at least one free licence (used_licenses < total_licenses).

Step 1 — Find your organization

Take the _id of the organization you want. The response also carries used_licenses and total_licenses, so you can confirm capacity before issuing, and vpn_name tells you which VPN is assigned.

Step 2 — Download the profile

The response is served as application/x-openvpn-profile with a Content-Disposition header naming the file, for example ClosedVPN-My Org.ovpn. The -OJ flags above tell curl to honour that name.

The response format

The body is not a bare .ovpn file. The first line is a # closedvpn-json comment carrying the organization’s exit nodes, followed by a blank line and then the OpenVPN profile.
OpenVPN ignores # comment lines, so the file works as-is with most clients. If your tooling parses the profile strictly, strip the first two lines:
Or read the exit-node metadata out of it:

Licences

A licence is consumed only when a new certificate is generated. used_licenses increments at that point. Re-downloading an existing certificate does not consume another. Licences are never released. used_licenses only ever increases — removing a member or having them leave does not free their licence — so an organization that cycles through members will need total_licenses raised. Once all licences are used, further members receive 403. The message differs by role: owners are told to acquire more licences, members are told to contact their owner.

Troubleshooting

The org_id query parameter is missing.
No VPN configuration is attached to the organization. Assign one, or create the organization with a vpnId — list the available VPNs with GET /auth/vpns.
The assigned VPN configuration has no create_cert entry in its commands map. An administrator must add it before certificates can be issued. Occurrences of CLIENT_NAME in the command are substituted at run time.
All licences are in use. used_licenses is never decremented — removing a member or having them leave does not release their licence — so the only remedy is to increase total_licenses.
You are not an active member of the organization named by org_id.
The org_id does not match any organization. Check the value against GET /auth/get-orgs. The same status is returned as User not found in the rare case where your own user record no longer exists.
The organization references a VPN configuration that no longer exists. An administrator must assign a valid VPN — list them with GET /auth/vpns.
The platform reached the VPN host but the create_cert command failed. The details field carries the host’s error output.
The create_cert command ran without error but produced no output. The command itself is likely misconfigured on the VPN host.

Checking the connection

Once connected, confirm the tunnel and read traffic counters with GET /auth/vpn-user-stats.
When you are not connected, or the VPN host cannot be reached, the response is {"connected": false} with no other fields. Check connected before reading the rest.