Tunnels

Updated 1 Oct 2026

Tunnels and their endpoints are managed under /v1/tunnels: create a tunnel and receive its token, add the endpoints a zone can use as its origin, and read whether the connector is running. What a tunnel is and how to run its connector: CacheGenie Tunnels. A zone uses an endpoint through ORIGIN_TYPE TUNNEL and TUNNEL_ENDPOINT on Zones.

The tunnel object#

  • TUNNEL_IDStringnine upper-case letters and digits. Never changes.
  • NAMEString1 to 64 characters.
  • ENABLEDInteger1, or 0 while the tunnel is switched off: its connector is refused and its zones answer with an error page.
  • STATEStringCONNECTED while a connector reports, DISCONNECTED when one has run but has not reported for 90 seconds, NEVER before the first connects (and again after a new token).
  • LOCATIONStringthe id of the location the connector is connected to, as Locations lists it. Empty unless CONNECTED.
  • LOCATION_NAMEStringthat location's name. Empty unless CONNECTED.
  • CONNECTED_ATIntegerwhen the connector last reported, Unix seconds; 0 before it first does, and once it has stopped cleanly.
  • AGENT_VERSIONStringthe connector's version, from its last report.
  • ENDPOINT_COUNTIntegerhow many endpoints the tunnel has.
  • CREATED_ATIntegerwhen it was made, Unix seconds.

Reading one tunnel adds ENDPOINTS, a list of endpoint objects. The token is never part of the object: it is in two answers only, the create and a new token, as TOKEN.

The endpoint object#

  • ENDPOINT_IDIntegerthe id a zone's TUNNEL_ENDPOINT takes.
  • NAMEString1 to 64 characters.
  • SCHEMEStringhttps or http, how the connector talks to the service.
  • HOSTStringthe service's address or hostname as seen from where the connector runs. An IPv6 address is returned as it is normally written, without brackets.
  • PORTInteger1 to 65535.
  • TARGETStringthe three together, such as https://192.168.1.5:443. Read only.
  • ZONESArraythe ids of the zones whose origin it is. Read only.

List tunnels#

GEThttps://api.cachegenie.com/v1/tunnels

Every tunnel on the account as DATA.TUNNELS, with MESSAGE Tunnels returned.

curl https://api.cachegenie.com/v1/tunnels \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "CODE": 200,
  "MESSAGE": "Tunnels returned.",
  "DATA": {
    "TUNNELS": [
      {
        "TUNNEL_ID": "TV83JLCPA",
        "NAME": "Office web server",
        "ENABLED": 1,
        "STATE": "CONNECTED",
        "LOCATION": "alpha1",
        "LOCATION_NAME": "Alpha City, XX",
        "CONNECTED_AT": 1790897840,
        "AGENT_VERSION": "1.0.0",
        "ENDPOINT_COUNT": 1,
        "CREATED_AT": 1790896000
      }
    ]
  }
}

Create a tunnel#

POSThttps://api.cachegenie.com/v1/tunnels
  • NAMEStringrequired1 to 64 characters.
curl -X POST https://api.cachegenie.com/v1/tunnels \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"NAME": "Office web server"}'

The answer is 201 with the new tunnel, an empty ENDPOINTS list and its TOKEN, and MESSAGE Tunnel created. TOKEN is in this answer only: keep it, it is not shown again. A missing or unusable name is 400 NAME is required: 1 to 64 characters.

{
  "CODE": 201,
  "MESSAGE":
    "Tunnel created. TOKEN is in this answer only: keep it, it is not shown again.",
  "DATA": {
    "TUNNEL_ID": "TV83JLCPA",
    "NAME": "Office web server",
    "ENABLED": 1,
    "STATE": "NEVER",
    "LOCATION": "",
    "LOCATION_NAME": "",
    "CONNECTED_AT": 0,
    "AGENT_VERSION": "",
    "ENDPOINT_COUNT": 0,
    "CREATED_AT": 1790896000,
    "ENDPOINTS": [],
    "TOKEN": "cgt_2af4b60e31412d74aec655d5fdfd2c05e39b672a595edaa11cf88b99d359e2ac"
  }
}

View a tunnel#

GEThttps://api.cachegenie.com/v1/tunnels/{TUNNEL_ID}

One tunnel with its ENDPOINTS, and MESSAGE Tunnel returned. A tunnel that does not exist or belongs to another account answers 404 Tunnel not found.

Update a tunnel#

POSThttps://api.cachegenie.com/v1/tunnels/{TUNNEL_ID}
  • NAMEStringoptional1 to 64 characters.
  • ENABLEDIntegeroptional1 to switch the tunnel on, 0 to switch it off.

A field left out keeps its value. The answer is the tunnel with its ENDPOINTS and MESSAGE Tunnel updated. Refusals are 400: NAME must be 1 to 64 characters. and ENABLED must be 1 or 0.

curl -X POST https://api.cachegenie.com/v1/tunnels/TV83JLCPA \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ENABLED": 0}'

Make a new token#

POSThttps://api.cachegenie.com/v1/tunnels/{TUNNEL_ID}/token

Replaces the token. The old one stops working at once and the connector using it is cut off, so start it again with the new one. The answer is the tunnel with its new TOKEN, and MESSAGE New token made. TOKEN is in this answer only, and the old token has stopped working. No body is needed.

Delete a tunnel#

DELETEhttps://api.cachegenie.com/v1/tunnels/{TUNNEL_ID}

Deletes the tunnel and its endpoints and answers Tunnel deleted. with an empty DATA. While one of its endpoints is a zone's origin the answer is 409 An endpoint of this tunnel is the origin of a zone.: give that zone another origin first.

List endpoints#

GEThttps://api.cachegenie.com/v1/tunnels/{TUNNEL_ID}/endpoints

The tunnel's endpoints as DATA.ENDPOINTS, with MESSAGE Endpoints returned.

{
  "CODE": 200,
  "MESSAGE": "Endpoints returned.",
  "DATA": {
    "ENDPOINTS": [
      {
        "ENDPOINT_ID": 7,
        "NAME": "Web server",
        "SCHEME": "https",
        "HOST": "192.168.1.5",
        "PORT": 443,
        "TARGET": "https://192.168.1.5:443",
        "ZONES": ["AB12CD34E"]
      }
    ]
  }
}

Add an endpoint#

POSThttps://api.cachegenie.com/v1/tunnels/{TUNNEL_ID}/endpoints
  • NAMEStringrequired1 to 64 characters.
  • SCHEMEStringrequiredhttps or http.
  • HOSTStringrequiredan IPv4 or IPv6 address, or a hostname the connector can resolve, such as app.internal or web.
  • PORTIntegeroptional1 to 65535. Left out or empty, 443 for https and 80 for http.
curl -X POST https://api.cachegenie.com/v1/tunnels/TV83JLCPA/endpoints \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"NAME": "Web server", "SCHEME": "https", "HOST": "192.168.1.5"}'

The answer is 201 with the endpoint object and MESSAGE Endpoint created. The connector picks it up within 30 seconds. Each refusal is a 400:

  • Give the endpoint a name of 1 to 64 characters.
  • Choose http or https: how the connector talks to your service.
  • Enter the host the connector can reach your service at: a hostname such as app.internal, or an address such as 192.168.1.5.
  • The port must be a number from 1 to 65535.

View, update or delete an endpoint#

GEThttps://api.cachegenie.com/v1/tunnels/{TUNNEL_ID}/endpoints/{ENDPOINT_ID}

One endpoint, with MESSAGE Endpoint returned. An id that is not one of the tunnel's answers 404 Endpoint not found.

POSThttps://api.cachegenie.com/v1/tunnels/{TUNNEL_ID}/endpoints/{ENDPOINT_ID}

NAME, SCHEME, HOST and PORT as above, each optional: a field left out keeps its value. Every zone using the endpoint follows the change. The answer is the endpoint with MESSAGE Endpoint updated., and the refusals are the add's.

DELETEhttps://api.cachegenie.com/v1/tunnels/{TUNNEL_ID}/endpoints/{ENDPOINT_ID}

Answers Endpoint deleted. with an empty DATA, or 409 This endpoint is the origin of a zone. while a zone uses it.

When a change cannot be confirmed#

A change whose answer from our database was lost is 503 The change could not be confirmed: the service is temporarily unavailable. Read the tunnel again before retrying., with Retry-After. It may or may not have been made, so read the tunnel before sending it again: a second create would make a second tunnel, and a second new token would replace the first.

Ask a human

To
Subject
Docs: Tunnels

Read and answered by the people who build CacheGenie, seven days a week.

Write to us