API-Driven Standalone Mode Usage
API-driven standalone mode stores routing configuration in memory rather than in a configuration file. A controller sends complete configuration snapshots to the dedicated standalone Admin API, and workers load accepted updates without a gateway restart. Acceptance does not mean that every worker has already applied the update. A bounded wait can confirm local worker synchronization.
caution
This feature is designed specifically for the APISIX Ingress Controller and is primarily intended for integration with ADC. APISIX provides an official, end-to-end, stateless Ingress Controller implementation. Do not use this feature directly unless you fully understand its internal workings and behavior.
This document provides a few examples for using APISIX in API-driven standalone mode. To learn more about the available configuration options, see the Admin API reference (but do not use these endpoints). These configuration options can be translated into JSON or YAML for use in API-driven standalone mode.
Examples
In API-driven standalone mode, you will be working with the /apisix/admin/configs API, instead of the traditional mode Admin API endpoints. The API accepts both JSON and YAML inputs.
The standalone mode Admin API has the same security requirements as the traditional mode Admin API configured in the config.yaml, including API key, (m)TLS, CORS, and IP allowlist.
Every PUT request requires an X-Digest header. The client chooses this identifier and must change it when the intended configuration changes. APISIX compares the identifier, not a server-computed hash of the body. Reusing the current digest returns 204 No Content without applying the new body, even when the body differs.
Each update is a complete snapshot, not a resource patch. Unless you explicitly retain a resource type's configuration version, omitted resources are removed. Validate the complete document before applying it, and retain the last known working snapshot so your controller can restore it after a restart or a failed rollout.
Get All Configurations
To get all configurations:
curl "http://127.0.0.1:9180/apisix/admin/configs" -H "X-API-KEY: ${ADMIN_API_KEY}"If you have no resource configured, you should see the following response:
{
"consumer_groups_conf_version": 0,
"secrets_conf_version": 0,
"global_rules_conf_version": 0,
"upstreams_conf_version": 0,
"ssls_conf_version": 0,
"protos_conf_version": 0,
"plugin_metadata_conf_version": 0,
"routes_conf_version": 0,
"stream_routes_conf_version": 0,
"plugins_conf_version": 0,
"services_conf_version": 0,
"plugin_configs_conf_version": 0,
"consumers_conf_version": 0
}Create a Resource
For instance, to create a route:
curl -i -X PUT "http://127.0.0.1:9180/apisix/admin/configs" \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "X-Digest: getting-started-v1" \
-H "Content-Type: application/json" \
-d '
{
"routes": [
{
"id": "getting-started-ip",
"uri": "/ip",
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}
]
}'Alternatively, you can also use the YAML input:
curl -X PUT "http://127.0.0.1:9180/apisix/admin/configs" \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "X-Digest: getting-started-yaml-v1" \
-H "Content-Type: application/yaml" \
--data-binary @- <<EOF
routes:
- id: getting-started-ip
uri: /ip
upstream:
type: roundrobin
nodes:
"httpbin.org:80": 1
EOFYou should receive an HTTP/1.1 202 Accepted response.
When you get all configurations, each *_conf_version has increased by 1. The response also includes the submitted digest and last-modified metadata. This reads the accepted snapshot; it is not proof that traffic on every worker uses that snapshot yet.
Validate Configurations
Before applying a later snapshot with a bounded wait, create apisix.json with the complete intended configuration. For example:
{
"routes": [
{
"id": "getting-started-ip",
"uri": "/ip",
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}
]
}Validate the file without applying it:
curl -i -X POST "http://127.0.0.1:9180/apisix/admin/configs/validate" \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "Content-Type: application/json" \
--data-binary @apisix.jsonYou should receive an HTTP/1.1 200 OK response if the configuration is valid. Validation does not change configuration versions or live resources. For supported resource sections, request limits, aggregated errors, and validation boundaries, see Schema Validation in the Admin API reference.
Wait for Local Workers
Add a wait query parameter to a configuration update to wait for workers on the receiving APISIX instance. The value is a timeout in milliseconds, capped at 60000. Omitting it or setting it to zero does not wait.
After validation succeeds, submit the snapshot with a new digest and a five-second wait:
curl -i -X PUT "http://127.0.0.1:9180/apisix/admin/configs?wait=5000" \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "X-Digest: rollout-v2" \
-H "Content-Type: application/json" \
--data-binary @apisix.jsonInterpret the status before sending traffic:
| Status | Meaning |
|---|---|
200 OK | All local workers reported the submitted digest for the resource types tracked by their HTTP and enabled stream subsystems. |
202 Accepted | The snapshot was accepted, but the request did not wait or the timeout expired before synchronization was confirmed. Workers may still apply it. |
204 No Content | The digest already matches the stored snapshot. No update or synchronization wait was performed. |
A timeout does not roll back the snapshot. Do not treat a subsequent same-digest 204 as a readiness check. Verify representative requests and complete your controller's rollout checks before shifting traffic. A local 200 does not confirm delivery to other APISIX instances, upstream health, or successful application traffic.
Update a Resource
In the API-driven mode, there are two version trackers APISIX uses to manage updates:
*_conf_version: Configuration version of a resource type.modifiedIndex: Modified index of a resource in a resource type.
For instance, routes with the same routes_conf_version can have different modifiedIndex.
The update rules of *_conf_version and modifiedIndex are evaluated in the following logic:
Suppose you send an update of a route with an upstream as such:
curl -X PUT "http://127.0.0.1:9180/apisix/admin/configs" \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "X-Digest: resources-v2000" \
-H "Content-Type: application/json" \
-d '
{
"routes_conf_version": 2000,
"routes": [
{
"modifiedIndex": 1,
"id": "ip",
"uri": "/ip",
"upstream_id": "u1"
}
],
"upstreams_conf_version": 2000,
"upstreams": [
{
"modifiedIndex": 1,
"id": "u1",
"nodes": {
"127.0.0.1:1980": 1,
"127.0.0.1:2980": 1
},
"type": "roundrobin"
}
]
}'When getting all configurations, you should see a response similar to the following:
{
"upstreams": [
{
"id": "u1",
"type": "roundrobin",
"modifiedIndex": 1,
"nodes": {
"127.0.0.1:2980": 1,
"127.0.0.1:1980": 1
}
}
],
"ssls_conf_version": 2,
"upstreams_conf_version": 2000,
"routes": [
{
"id": "ip",
"upstream_id": "u1",
"modifiedIndex": 1,
"uri": "/ip"
}
],
"protos_conf_version": 2,
"consumers_conf_version": 2,
"services_conf_version": 2,
"plugin_configs_conf_version": 2,
"plugin_metadata_conf_version": 2,
"consumer_groups_conf_version": 2,
"secrets_conf_version": 2,
"global_rules_conf_version": 2,
"routes_conf_version": 2000
}Now if you increase the upstreams_conf_version, update modifiedIndex and node address of the upstream, update the route URI while keeping routes_conf_version unchanged:
curl -X PUT "http://127.0.0.1:9180/apisix/admin/configs" \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "X-Digest: resources-v2001" \
-H "Content-Type: application/json" \
-d '
{
"routes_conf_version": 2000,
"routes": [
{
"modifiedIndex": 1,
"id": "ip",
"uri": "/new-ip",
"upstream_id": "u1"
}
],
"upstreams_conf_version": 2001,
"upstreams": [
{
"modifiedIndex": 5,
"id": "u1",
"nodes": {
"127.0.0.1:1980": 1,
"127.0.0.1:3980": 1
},
"type": "roundrobin"
}
]
}'When getting all configurations, you should see a response similar to the following, while route configuration is unchanged and upstream has been updated:
{
"upstreams": [
{
"id": "u1",
"type": "roundrobin",
"modifiedIndex": 5,
"nodes": {
"127.0.0.1:3980": 1,
"127.0.0.1:1980": 1
}
}
],
"services_conf_version": 3,
"plugin_configs_conf_version": 3,
"plugin_metadata_conf_version": 3,
"consumer_groups_conf_version": 3,
"secrets_conf_version": 3,
"routes": [
{
"id": "ip",
"uri": "/ip",
"modifiedIndex": 1,
"upstream_id": "u1"
}
],
"upstreams_conf_version": 2001,
"routes_conf_version": 2000,
"consumers_conf_version": 3,
"ssls_conf_version": 3,
"global_rules_conf_version": 3,
"protos_conf_version": 3
}Clear All Resources
An empty snapshot removes all routing and plugin resources. Perform this only when you intend to stop serving the configured traffic, and keep a complete backup for restoration:
curl -X PUT "http://127.0.0.1:9180/apisix/admin/configs" \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-H "X-Digest: clear-resources-v1" \
-H "Content-Type: application/json" \
-d '{}'Note that this operation does not reset the *_conf_version. They will continue to increment.