Skip to main content
skill CX Codex

neo4j-aura-provisioning-skill — Claude Code skill: Aura via CLI

Creates and manages Neo4j Aura instances through aura-cli or the REST API: pause, resume, resize, delete, credential download.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add neo4j-contrib/neo4j-skills --skill neo4j-aura-provisioning-skill -a claude-code
Open on GitHub

What neo4j-aura-provisioning-skill does

The skill covers the full instance lifecycle: create, pause, resume, resize, delete. It drives aura-cli v1.7+ or the REST API directly, and polls async status until an instance reaches running. A tier table maps free-db through enterprise-db to memory, GDS support and replicas, and region codes are listed for create calls.

Auth setup uses client credentials OAuth2. REST calls need a bearer token that expires after 3600 seconds, so a 403 means refreshing it. The instance password appears once in the creation response and is never retrievable — lose it and the only path is delete and recreate. Keep that output in a file rather than scrolling back through terminal history.

Cypher queries and Graph Data Science algorithms are out of scope; separate skills handle those, as do neo4j-admin and cypher-shell. Install runs through npx skills add, except on GitHub Copilot, where the command is gh skill install.

What it helps with

  • spin up an AuraDB instance and write the password straight into .env
  • pause an instance that sits idle
  • wait for running before a driver connects
  • declare Aura provisioning in Terraform
  • pick a tier for the workload: Free, Professional or Business Critical

Example prompts for the agent

  • Create an AuraDB Professional instance in europe-west1 and save the response to aura-creds.json
  • Pause instance $INSTANCE_ID and poll until the status is paused
  • Set up aura-cli auth with client credentials and list my tenants

How to install neo4j-aura-provisioning-skill

1Skills CLI (Vercel)

npx skills add neo4j-contrib/neo4j-skills --skill neo4j-aura-provisioning-skill -a claude-code

2Manually: put the files in place

~/.claude/skills/neo4j-aura-provisioning-skill/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/neo4j-aura-provisioning-skill/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about neo4j-aura-provisioning-skill

How do I install neo4j-aura-provisioning-skill in Claude?

Run npx skills add neo4j-contrib/neo4j-skills --skill neo4j-aura-provisioning-skill -a claude-code. The skill file then lives at ~/.claude/skills/neo4j-aura-provisioning-skill/SKILL.md.

What does neo4j-aura-provisioning-skill do?

It provisions and manages Neo4j Aura instances: create, pause, resume, resize, delete and credential download. Calls go through aura-cli or the REST API, with async status polling.

Can this skill run Cypher queries?

No. Use neo4j-cypher-skill for queries against a running database, and neo4j-gds-skill or neo4j-aura-graph-analytics-skill for GDS algorithms.

Source text

SKILL.md · MIT
---
name: neo4j-aura-provisioning-skill
description: Provisions and manages Neo4j Aura instances via CLI (aura-cli v1.7+) or REST API.
  Use when creating, pausing, resuming, resizing, or deleting AuraDB Free/Professional/Business Critical/VDC
  instances; downloading credentials; scripting CI/CD pipelines; polling async status; or using the
  Terraform neo4j-labs/neo4jaura provider. Covers auth setup (client credentials OAuth2), credential
  lifecycle (download once — never recoverable), instance type selection, region codes, and Python
  provisioning scripts. Does NOT handle Cypher queries — use neo4j-cypher-skill.
  Does NOT cover Graph Data Science algorithms — use neo4j-gds-skill or neo4j-aura-graph-analytics-skill.
  Does NOT cover neo4j-admin/cypher-shell — use neo4j-cli-tools-skill.
version: 1.0.5
allowed-tools: Bash WebFetch
---

## When to Use
- Creating an Aura instance (CLI, REST API, Python, Terraform)
- Pausing, resuming, resizing, or deleting an instance
- Downloading initial credentials from creation response
- Polling instance status: `creating` → `running`
- Setting up CI/CD provisioning or teardown pipelines
- Choosing instance tier (Free vs Professional vs Business Critical vs VDC)

## When NOT to Use
- **Cypher queries against running DB** → `neo4j-cypher-skill`
- **GDS algorithms on Aura** → `neo4j-gds-skill` (Pro with plugin) or `neo4j-aura-graph-analytics-skill` (serverless)
- **neo4j-admin / cypher-shell** → `neo4j-cli-tools-skill`
- **Application driver setup** → use a language driver skill (python, javascript, java, go, dotnet)

---

## Instance Tier Decision Table

| Tier | API type code | Memory | GDS | Replicas | Use when |
|---|---|---|---|---|---|
| AuraDB Free | `free-db` | 1 GB | ❌ | ❌ | Dev/demo; ≤200k nodes/400k rels |
| AuraDB Professional | `professional-db` | 2–64 GB | plugin available | ❌ | Production workloads |
| AuraDB Business Critical | `business-critical` | 4–384 GB | plugin available | ✅ | HA, multi-AZ, SLA |
| AuraDB VDC | `enterprise-db` | custom | ✅ | ✅ | Dedicated infra, compliance |
| AuraDS Professional | `professional-ds` | 2–64 GB | ✅ built-in | ❌ | Data science / GDS |
| AuraDS Enterprise | `enterprise-ds` | custom | ✅ | ✅ | Enterprise GDS |

**AuraDB Free limits**: 200k nodes, 400k rels; auto-pauses after 72 h inactivity; deleted if paused >30 days; no resize.

---

## Auth Setup

### CLI (aura-cli v1.7+)

Install (binary, not pip):
```bash
# macOS
curl -L https://github.com/neo4j/aura-cli/releases/latest/download/aura-cli-darwin-amd64.tar.gz | tar xz
sudo mv aura-cli /usr/local/bin/
aura-cli -v          # verify
```

Add credentials (from console.neo4j.io → Account Settings → API Credentials):
```bash
aura-cli credential add \
  --name "my-creds" \
  --client-id "$AURA_CLIENT_ID" \
  --client-secret "$AURA_CLIENT_SECRET"
aura-cli credential use --name "my-creds"
```

Verify:
```bash
aura-cli instance list --output table
```

### REST API — Get Bearer Token

Token endpoint: `POST https://api.neo4j.io/oauth/token`
Token expires: **3600 s (1 h)**. On 403 → refresh token.

```bash
TOKEN=$(curl -s --request POST 'https://api.neo4j.io/oauth/token' \
  --user "${AURA_CLIENT_ID}:${AURA_CLIENT_SECRET}" \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=client_credentials' \
  | jq -r '.access_token')
echo "Token: ${TOKEN:0:20}..."
```

Use in all subsequent calls: `--header "Authorization: Bearer $TOKEN"`

---

## Step 1 — List Tenants (Projects)

CLI:
```bash
aura-cli tenants list --output table
# Copy TENANT_ID for create operations
```

REST:
```bash
curl -s https://api.neo4j.io/v1/tenants \
  -H "Authorization: Bearer $TOKEN" | jq '.data[] | {id, name}'
```

---

## Step 2 — Create Instance

CRITICAL: **Capture output immediately.** Initial password shown ONCE — never retrievable again.
If lost: delete and recreate. Store `aura-creds.json` before doing anything else.

### CLI

```bash
aura-cli instance create \
  --name "my-instance" \
  --cloud-provider gcp \
  --region europe-west1 \
  --type professional-db \
  --tenant-id "$TENANT_ID" \
  --output json | tee aura-creds.json

# Extract for .env
INSTANCE_ID=$(jq -r '.id' aura-creds.json)
PASSWORD=$(jq -r '.password' aura-creds.json)
```

### REST API (full create)

```bash
RESPONSE=$(curl -s -X POST https://api.neo4j.io/v1/instances \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name":           "my-instance",
    "cloud_provider": "gcp",
    "region":         "europe-west1",
    "type":           "professional-db",
    "tenant_id":      "'"$TENANT_ID"'",
    "memory":         "4GB",
    "version":        "5"
  }')
echo "$RESPONSE" | tee aura-creds.json
INSTANCE_ID=$(echo "$RESPONSE" | jq -r '.data.id')
PASSWORD=$(echo "$RESPONSE"   | jq -r '.data.password')
```

Instance create request body fields:

| Field | Required | Values |
|---|---|---|
| `name` | ✅ | any string |
| `cloud_provider` | ✅ | `gcp` `aws` `azure` |
| `region` | ✅ | see region table |
| `type` | ✅ | see tier table |
| `tenant_id` | ✅ | from tenant list |
| `memory` | ✗ | `1GB` `2GB` `4GB` `8GB` … `384GB` |
| `version` | ✗ | `5` (default) |

---

## Step 3 — Poll Until RUNNING (CRITICAL — All Ops Are Async)

ALL lifecycle operations (create, pause, resume, resize) are async. Do NOT attempt connection or next operation until status = `running` (or `paused` for pause op).

```bash
poll_status() {
  local INSTANCE_ID=$1 TARGET=$2 MAX_WAIT=${3:-600}
  local ELAPSED=0 STATUS
  echo "Polling for status=$TARGET (max ${MAX_WAIT}s)..."
  while [ $ELAPSED -lt $MAX_WAIT ]; do
    STATUS=$(aura-cli instance get --instance-id "$INSTANCE_ID" --output json \
             | jq -r '.status' 2>/dev/null)
    echo "  [${ELAPSED}s] status=$STATUS"
    [ "$STATUS" = "$TARGET" ] && echo "Ready." && return 0
    [ "$STATUS" = "destroying" ] && echo "ERROR: instance is being destroyed" && return 1
    sleep 10; ELAPSED=$((ELAPSED + 10))
  done
  echo "TIMEOUT after ${MAX_WAIT}s — last status: $STATUS" && return 1
}

poll_status "$INSTANCE_ID" "running" 600
```

REST equivalent:
```bash
while true; do
  STATUS=$(curl -s "https://api.neo4j.io/v1/instances/$INSTANCE_ID" \
    -H "Authorization: Bearer $TOKEN" | jq -r '.data.status')
  [ "$STATUS" = "running" ] && break
  sleep 10
done
```

Status lifecycle:
```
creating → running → pausing → paused → resuming → running
                  ↘ destroying → (gone)
```

---

## Step 4 — Write .env and Verify

```bash
CONNECTION_URI="neo4j+s://${INSTANCE_ID}.databases.neo4j.io"

cat > .env <<EOF
NEO4J_URI=${CONNECTION_URI}
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=${PASSWORD}
NEO4J_DATABASE=neo4j
AURA_INSTANCE_ID=${INSTANCE_ID}
EOF

# Ensure .env never committed
grep -q '^\.env$' .gitignore 2>/dev/null || echo '.env' >> .gitignore

# Verify connectivity
cypher-shell -a "$CONNECTION_URI" -u neo4j -p "$PASSWORD" "RETURN 'connected' AS status"
```

---

## Step 5 — Lifecycle Operations

All operations require instance in the correct state. Wrong-state ops return 4xx error.

### Pause
Required state: `running`
```bash
aura-cli instance pause --instance-id "$INSTANCE_ID"
poll_status "$INSTANCE_ID" "paused" 600
```

### Resume
Required state: `paused`
```bash
aura-cli instance resume --instance-id "$INSTANCE_ID"
poll_status "$INSTANCE_ID" "running" 900   # resume can take longer
```

### Resize (Professional+ only — NOT Free)
Required state: `running`; instance remains available during resize.
```bash
# REST only — CLI resize not available in v1.7
curl -s -X PATCH "https://api.neo4j.io/v1/instances/$INSTANCE_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"memory": "8GB"}'
poll_status "$INSTANCE_ID" "running" 600
# Cannot reduce below current usage level
```

### Delete
IRREVERSIBLE. Export snapshots first if data needed.
```bash
aura-cli instance delete --instance-id "$INSTANCE_ID"
# No poll needed — immediate
```

REST:
```bash
curl -s -X DELETE "https://api.neo4j.io/v1/instances/$INSTANCE_ID" \
  -H "Authorization: Bearer $TOKEN"
```

---

## Python CI/CD Provisioning Script

```python
import os, time, requests

CLIENT_ID     = os.environ["AURA_CLIENT_ID"]
CLIENT_SECRET = os.environ["AURA_CLIENT_SECRET"]
BASE          = "https://api.neo4j.io/v1"

def get_token() -> str:
    r = requests.post(
        "https://api.neo4j.io/oauth/token",
        auth=(CLIENT_ID, CLIENT_SECRET),
        data={"grant_type": "client_credentials"},
    )
    r.raise_for_status()
    return r.json()["access_token"]

def auth_headers(token: str) -> dict:
    return {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}

def create_instance(token: str, tenant_id: str, **kwargs) -> dict:
    payload = {"tenant_id": tenant_id, "version": "5", **kwargs}
    r = requests.post(f"{BASE}/instances", headers=auth_headers(token), json=payload)
    r.raise_for_status()
    return r.json()["data"]   # contains id, password, connection_url

def poll_status(token: str, instance_id: str, target: str, timeout: int = 600) -> None:
    deadline = time.time() + timeout
    while time.time() < deadline:
        r = requests.get(f"{BASE}/instances/{instance_id}", headers=auth_headers(token))
        r.raise_for_status()
        status = r.json()["data"]["status"]
        print(f"  status={status}")
        if status == target:
            return
        if status == "destroying":
            raise RuntimeError("Instance destroyed unexpectedly")
        time.sleep(10)
    raise TimeoutError(f"Instance {instance_id} did not reach '{target}' in {timeout}s")

# --- usage ---
token    = get_token()
instance = create_instance(
    token,
    tenant_id = os.environ["AURA_TENANT_ID"],
    name           = "ci-test-instance",
    cloud_provider = "aws",
    region         = "us-east-1",
    type           = "professional-db",
    memory         = "2GB",
)
# SAVE CREDENTIALS IMMEDIATELY — password never retrievable again
print(f"ID:       {instance['id']}")
print(f"URI:      neo4j+s://{instance['id']}.databases.neo4j.io")
print(f"Password: {instance['password']}")   # log to secure vault NOW

poll_status(token, instance["id"], "running", timeout=600)
print("Instance ready.")
```

---

## Region Codes

### AWS
| Region code | Location |
|---|---|
| `us-east-1` | N. Virginia |
| `us-east-2` | Ohio |
| `us-west-2` | Oregon |
| `eu-west-1` | Ireland |
| `eu-west-3` | Paris |
| `eu-central-1` | Frankfurt |
| `ap-southeast-1` | Singapore |
| `ap-southeast-2` | Sydney |
| `ap-south-1` | Mumbai |
| `sa-east-1` | São Paulo |

### GCP
| Region code | Location |
|---|---|
| `europe-west1` | Belgium |
| `europe-west3` | Frankfurt |
| `europe-west4` | Netherlands |
| `us-central1` | Iowa |
| `us-east1` | S. Carolina |
| `us-east4` | N. Virginia |
| `asia-east1` | Taiwan |
| `asia-northeast1` | Tokyo |
| `asia-southeast1` | Singapore |
| `australia-southeast1` | Sydney |

### Azure
| Region code | Location |
|---|---|
| `eastus` | E. US |
| `eastus2` | E. US 2 |
| `westeurope` | Netherlands |
| `northeurope` | Ireland |
| `uksouth` | London |
| `southeastasia` | Singapore |
| `brazilsouth` | Brazil |
| `koreacentral` | Korea |

Enterprise tiers (Business Critical, VDC) add 20+ additional regions per provider. Check console for full list.
Free tier: GCP only; limited subset of regions.

---

## Terraform Provider

```hcl
terraform {
  required_providers {
    neo4jaura = {
      source  = "neo4j-labs/neo4jaura"
    }
  }
}

provider "neo4jaura" {
  client_id     = var.aura_client_id       # or AURA_CLIENT_ID env var
  client_secret = var.aura_client_secret   # or AURA_CLIENT_SECRET env var
}

resource "neo4jaura_instance" "db" {
  name           = "prod-db"
  type           = "professional-db"
  cloud_provider = "gcp"
  region         = "europe-west1"
  memory         = "4GB"
  project_id     = var.aura_project_id   # Terraform uses project_id (REST API: tenant_id)
}

output "neo4j_uri" {
  value     = neo4jaura_instance.db.connection_url
  sensitive = false
}
output "neo4j_password" {
  value     = neo4jaura_instance.db.password
  sensitive = true
}
```

After `terraform apply`: poll status before marking infra ready — Terraform resource creation returns when API call completes, not when DB is `running`.

---

## Common Errors

| Error | Cause | Fix |
|---|---|---|
| `403 Forbidden` after working | Token expired (1 h TTL) | Re-run `get_token()` |
| `409 Conflict` on create | Name already exists in tenant | Change name or delete existing |
| `422` on pause | Instance not `running` | Check status; wait for ongoing op to finish |
| `422` on resume | Instance not `paused` | Check status |
| `422` on resize | Below current usage | Reduce data first; can't shrink below usage |
| Region not found | Tier doesn't support that region | Use `Free` tier on GCP only; Pro/BC on all 3 clouds |
| Credentials lost after create | Password only returned at create time | Delete + recreate — no reset exists |
| `429 Too Many Requests` | Rate limit hit (25 req/min Free, 125 req/min Pro+) | Add `time.sleep(2)` between polling calls |
| `instance list` returns empty | Wrong credential active | `aura-cli credential use --name <name>` |

---

## API Rate Limits

| Tier | Requests/minute |
|---|---|
| Free / Pro Trial (no billing) | 25 |
| Pro with billing, BC, VDC | 125 |

Poll interval: ≥10 s to stay within limits on Free; 5 s safe on Pro+.
On `Retry-After` header in 5xx response: wait that many seconds before retry.

---

## Security Rules

- Write initial credentials to `.env`; verify `.env` in `.gitignore` before proceeding
- Never print `PASSWORD` in CI logs — write to secrets vault (AWS Secrets Manager, GitHub secret, Vault)
- Use `from_env()` / `os.environ` — never hardcode credentials
- If `.env` absent: `python-dotenv` `load_dotenv()` auto-loads; do NOT prompt user unless loading fails

---

## WebFetch — Current Docs

| Need | URL |
|---|---|
| REST API spec (OpenAPI) | `https://neo4j.com/docs/aura/platform/api/specification/` |
| CLI reference | `https://neo4j.com/docs/aura/aura-cli/` |
| Region list | `https://neo4j.com/docs/aura/managing-instances/regions/` |
| Auth details | `https://neo4j.com/docs/aura/api/authentication/` |
| Instance actions | `https://neo4j.com/docs/aura/managing-instances/instance-actions/` |

---

## Checklist
- [ ] `.env` created with URI/user/password; `.env` in `.gitignore`
- [ ] Initial credentials saved to secure storage immediately after create
- [ ] `poll_status` called after create — do NOT connect before status = `running`
- [ ] `poll_status` called after pause/resume
- [ ] Correct tier selected (Free for dev, Pro+ for production, BC for HA)
- [ ] Region confirmed available for chosen tier and cloud provider
- [ ] Tenant ID provided for all create/list operations (required in multi-tenant orgs)
- [ ] Token refreshed if > 1 h old (or 403 received)
- [ ] Delete confirmed by user — data loss is permanent, no recovery

© neo4j-contrib · MIT · neo4j-contrib/neo4j-skills

Similar skills

All skills for Data and databases →

From the same set18

neo4j-security-skill This skill walks an agent through Neo4j user, role and privilege management in Cypher against the system database. Useful when access has to be provisioned by script instead of by hand. CX Codex +1 824installs neo4j-genai-plugin-skill A skill for calling Neo4j GenAI Plugin functions and procedures inside Cypher: embeddings, completion, chat, tokenization. CX Codex +1 812installs neo4j-graphql-skill A skill that walks your agent through building a GraphQL API on @neo4j/graphql: type definitions, directives, JWT auth and Apollo Server wiring. CX Codex +1 809installs neo4j-aura-graph-analytics-skill A skill that walks your agent through serverless Aura Graph Analytics GDS Sessions: graph projection, memory estimation, async jobs and write-back. CX Codex +1 798installs neo4j-kafka-skill Sets up the Neo4j Connector for Kafka in both directions and the native CDC API. Useful when Kafka events have to land in a graph or Neo4j changes need to reach topics. CX Codex +1 772installs neo4j-driver-java-skill Tells your agent how to wire Java or Kotlin into Neo4j: driver setup, sessions, transactions, connection pool. CX Codex +1 770installs neo4j-aura-agent-skill A Claude skill that walks the v2beta1 REST API for Neo4j Aura Agents: create them, wire up tools, invoke them with plain-language queries. CX Codex +1 760installs neo4j-snowflake-graph-analytics-skill A skill for running Neo4j graph algorithms inside Snowflake through SQL CALL, with data staying put. Useful when your tables already live in Snowflake. CX Codex +1 752installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor