Documentation

Auto-Tagging

ZopNight predicts environment tags (prod, staging, dev) and a noStop flag for resources that are missing them. Predictions come from name patterns, existing tags, topology, and resource characteristics — not from an LLM — so they are reproducible and cheap to re-run.

Why this matters

Tag-based cost attribution, schedules, and recommendation rules all rely on consistent environment tagging. In practice most accounts have partial coverage — auto-tagging closes the gap so Showback and Schedules can rely on a full set of tags.

How predictions work

  1. Discoverer emits a resource.discovered event with name, tags, parent, and type.
  2. Recommender evaluates deterministic rules (e.g. name contains prod-, or the parent EKS cluster is already tagged).
  3. Each prediction carries a confidence score (1–100) and a reason string.
  4. Predictions land in pending status. They are never auto-applied — you accept or reject them.

Accepted predictions are merged with cloud tags when computing Showback, so a resource can be attributed to a team or tag key even when the cloud account owner hasn't tagged it yet.

Lifecycle

When a resource is deleted in the cloud, the recommender receives a resource.deleted event and drops the tagger row for that resource so the review queue never shows suggestions for resources you no longer own. A full refresh sweep (POST /recommendations/refresh) acts as a catch-up — any tagger row whose resource_uid is no longer in the discoverer set is removed.

List Suggestions

GET
/autotagging

Paginated list of auto-tagging suggestions for the current org.

Query Parameters

ParameterDescription
statusLifecycle filter: pending | accepted | rejected. Omit for all.
providerCloud provider filter: aws | gcp | azure.
acceptedLegacy boolean filter — true returns accepted, false returns pending. Prefer status.
pagePage number (default: 1).
limitItems per page (default: 10, max: 100). `size` is accepted as a deprecated alias.
Responsejson
{
  "items": [
    {
      "id": "tag_001",
      "orgId": "org_42",
      "resourceUid": "i-0abc123def456",
      "resourceName": "prod-api-server",
      "resourceType": "aws-ec2",
      "provider": "aws",
      "cloudAccountId": "acc_1",
      "predictedEnv": "prod",
      "predictedNoStop": true,
      "extraTags": { "owner": "platform" },
      "confidence": 92,
      "reason": "Name contains 'prod', has production cluster parent, runs 24/7",
      "acceptedAt": null,
      "rejectedAt": null,
      "createdAt": "2026-04-20T08:00:00Z",
      "updatedAt": "2026-04-20T08:00:00Z"
    }
  ],
  "total": 15,
  "page": 1,
  "limit": 20,
  "hasMore": false
}

Count Suggestions

GET
/autotagging/count

Total count for a given status and provider. Used to render tab badges and pagination totals — fetch once per (status, provider) pair.

Accepts the same status and provider filters as the list endpoint. Returns a single integer.

Responsejson
{
  "count": 15
}

Accept or Reject

PATCH
/autotagging/{resourceUid}

Move a suggestion to accepted or rejected. Supports partial-accept of individual tag fields.

Pass the verdict as status. For partial accept, also pass any of acceptEnv, acceptNoStop, or acceptOwner — fields set to false are cleared before the row is marked accepted, fields omitted keep the predicted value.

Accept the full predictionbash
curl -X PATCH https://zopnight.com/api/autotagging/i-0abc123def456 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "status": "accepted" }'
Accept env only, drop the noStop tagbash
curl -X PATCH https://zopnight.com/api/autotagging/i-0abc123def456 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "accepted",
    "acceptEnv": true,
    "acceptNoStop": false
  }'
Rejectbash
curl -X PATCH https://zopnight.com/api/autotagging/i-0abc123def456 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "status": "rejected" }'

Accept / Reject for slash-containing UIDs

POST
/autotagging/accept

Full-accept variant for resource UIDs that contain slashes (e.g. GCP //container.googleapis.com/... paths), which can't traverse the PATCH route's URL pattern.

Requestbash
curl -X POST https://zopnight.com/api/autotagging/accept \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "resourceUid": "//container.googleapis.com/projects/.../clusters/c1" }'

Full-accept only

The body endpoints are not deprecated — they handle a real URL-routing constraint. They do not support partial-accept; use PATCH when the UID is path-safe and you want partial selection.
POST
/autotagging/reject

Reject variant for slash-containing UIDs. Same body shape as /autotagging/accept.

Requestbash
curl -X POST https://zopnight.com/api/autotagging/reject \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "resourceUid": "//container.googleapis.com/projects/.../clusters/c1" }'

Confidence Buckets

BucketRangeGuidance
High80–100Safe to accept in bulk — multiple independent signals agree (name + parent + sibling tags).
Medium50–79Review individually — a single signal drove the prediction.
Low< 50Not surfaced as a primary suggestion; visible to administrators only.