diff --git a/Makefile b/Makefile index 3f6e8f4..2c900cc 100644 --- a/Makefile +++ b/Makefile @@ -111,8 +111,8 @@ GO_SRCS := $(shell ( \ $(DOCS_JSON) $(DOCS_YAML): $(GO_SRCS) @echo ">> Generating Swagger docs..." @if ! command -v swag >/dev/null 2>&1; then \ - echo "Installing swag..."; \ - $(GOINSTALL) github.com/swaggo/swag/cmd/swag@latest; \ + echo "Installing swag/v2 CLI @v2.0.0-rc4..."; \ + $(GOINSTALL) github.com/swaggo/swag/v2/cmd/swag@v2.0.0-rc4; \ fi @rm -rf docs/swagger.* docs/docs.go @swag init -g $(MAIN) -o docs diff --git a/docs/docs.go b/docs/docs.go index c3bb739..f97bc88 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,11 +1,4060 @@ -// Code generated by swaggo/swag. DO NOT EDIT. - +// Package docs Code generated by swaggo/swag. DO NOT EDIT package docs -import "github.com/swaggo/swag/v2" +import "github.com/swaggo/swag" const docTemplate = `{ - "schemes": {{ marshal .Schemes }},"swagger":"2.0","info":{"description":"{{escape .Description}}","title":"{{.Title}}","contact":{"name":"GlueOps"},"version":"{{.Version}}"},"host":"{{.Host}}","basePath":"{{.BasePath}}","paths":{"/.well-known/jwks.json":{"get":{"description":"Returns the JSON Web Key Set for token verification","produces":["application/json"],"tags":["Auth"],"summary":"Get JWKS","operationId":"getJWKS","responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.JWKS"}}}}},"/admin/archer/jobs":{"get":{"security":[{"BearerAuth":[]}],"description":"Paginated background jobs with optional filters. Search ` + "`" + `q` + "`" + ` may match id, type, error, payload (implementation-dependent).","consumes":["application/json"],"produces":["application/json"],"tags":["ArcherAdmin"],"summary":"List Archer jobs (admin)","operationId":"AdminListArcherJobs","parameters":[{"enum":["queued","running","succeeded","failed","canceled","retrying","scheduled"],"type":"string","description":"Filter by status","name":"status","in":"query"},{"type":"string","description":"Filter by queue name / worker name","name":"queue","in":"query"},{"type":"string","description":"Free-text search","name":"q","in":"query"},{"type":"integer","default":1,"description":"Page number","name":"page","in":"query"},{"maximum":100,"minimum":1,"type":"integer","default":25,"description":"Items per page","name":"page_size","in":"query"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.PageJob"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"forbidden","schema":{"type":"string"}},"500":{"description":"internal error","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]}],"description":"Create a job immediately or schedule it for the future via ` + "`" + `run_at` + "`" + `.","consumes":["application/json"],"produces":["application/json"],"tags":["ArcherAdmin"],"summary":"Enqueue a new Archer job (admin)","operationId":"AdminEnqueueArcherJob","parameters":[{"description":"Job parameters","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.EnqueueRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.Job"}},"400":{"description":"invalid json or missing fields","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"forbidden","schema":{"type":"string"}},"500":{"description":"internal error","schema":{"type":"string"}}}}},"/admin/archer/jobs/{id}/cancel":{"post":{"security":[{"BearerAuth":[]}],"description":"Set job status to canceled if cancellable. For running jobs, this only affects future picks; wire to Archer if you need active kill.","consumes":["application/json"],"produces":["application/json"],"tags":["ArcherAdmin"],"summary":"Cancel an Archer job (admin)","operationId":"AdminCancelArcherJob","parameters":[{"type":"string","description":"Job ID","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.Job"}},"400":{"description":"invalid job or not cancellable","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"forbidden","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}}}}},"/admin/archer/jobs/{id}/retry":{"post":{"security":[{"BearerAuth":[]}],"description":"Marks the job retriable (DB flip). Swap this for an Archer admin call if you expose one.","consumes":["application/json"],"produces":["application/json"],"tags":["ArcherAdmin"],"summary":"Retry a failed/canceled Archer job (admin)","operationId":"AdminRetryArcherJob","parameters":[{"type":"string","description":"Job ID","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.Job"}},"400":{"description":"invalid job or not eligible","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"forbidden","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}}}}},"/admin/archer/queues":{"get":{"security":[{"BearerAuth":[]}],"description":"Summary metrics per queue (pending, running, failed, scheduled).","consumes":["application/json"],"produces":["application/json"],"tags":["ArcherAdmin"],"summary":"List Archer queues (admin)","operationId":"AdminListArcherQueues","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.QueueInfo"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"forbidden","schema":{"type":"string"}},"500":{"description":"internal error","schema":{"type":"string"}}}}},"/annotations":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns annotations for the organization in X-Org-ID. Filters: ` + "`" + `key` + "`" + `, ` + "`" + `value` + "`" + `, and ` + "`" + `q` + "`" + ` (key contains). Add ` + "`" + `include=node_pools` + "`" + ` to include linked node pools.","consumes":["application/json"],"produces":["application/json"],"tags":["Annotations"],"summary":"List annotations (org scoped)","operationId":"ListAnnotations","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Exact key","name":"key","in":"query"},{"type":"string","description":"Exact value","name":"value","in":"query"},{"type":"string","description":"key contains (case-insensitive)","name":"q","in":"query"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.AnnotationResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list annotations","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Creates an annotation.","consumes":["application/json"],"produces":["application/json"],"tags":["Annotations"],"summary":"Create annotation (org scoped)","operationId":"CreateAnnotation","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Annotation payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateAnnotationRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.AnnotationResponse"}},"400":{"description":"invalid json / missing fields","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"create failed","schema":{"type":"string"}}}}},"/annotations/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns one annotation. Add ` + "`" + `include=node_pools` + "`" + ` to include node pools.","consumes":["application/json"],"produces":["application/json"],"tags":["Annotations"],"summary":"Get annotation by ID (org scoped)","operationId":"GetAnnotation","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Annotation ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.AnnotationResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes the annotation.","consumes":["application/json"],"produces":["application/json"],"tags":["Annotations"],"summary":"Delete annotation (org scoped)","operationId":"DeleteAnnotation","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Annotation ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}},"patch":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Partially update annotation fields.","consumes":["application/json"],"produces":["application/json"],"tags":["Annotations"],"summary":"Update annotation (org scoped)","operationId":"UpdateAnnotation","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Annotation ID (UUID)","name":"id","in":"path","required":true},{"description":"Fields to update","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.UpdateAnnotationRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.AnnotationResponse"}},"400":{"description":"invalid id / invalid json","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"update failed","schema":{"type":"string"}}}}},"/auth/logout":{"post":{"consumes":["application/json"],"produces":["application/json"],"tags":["Auth"],"summary":"Revoke refresh token family (logout everywhere)","operationId":"Logout","parameters":[{"description":"Refresh token","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.LogoutRequest"}}],"responses":{"204":{"description":"No Content"}}}},"/auth/refresh":{"post":{"consumes":["application/json"],"produces":["application/json"],"tags":["Auth"],"summary":"Rotate refresh token","operationId":"Refresh","parameters":[{"description":"Refresh token","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.RefreshRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TokenPair"}}}}},"/auth/{provider}/callback":{"get":{"produces":["application/json"],"tags":["Auth"],"summary":"Handle social login callback","operationId":"AuthCallback","parameters":[{"type":"string","description":"google|github","name":"provider","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TokenPair"}}}}},"/auth/{provider}/start":{"post":{"description":"Returns provider authorization URL for the frontend to redirect","produces":["application/json"],"tags":["Auth"],"summary":"Begin social login","operationId":"AuthStart","parameters":[{"type":"string","description":"google|github","name":"provider","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.AuthStartResponse"}}}}},"/healthz":{"get":{"description":"Returns 200 OK when the service is up","consumes":["application/json"],"produces":["application/json"],"tags":["Health"],"summary":"Basic health check","operationId":"HealthCheck // operationId","responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/handlers.HealthStatus"}}}}},"/labels":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns node labels for the organization in X-Org-ID. Filters: ` + "`" + `key` + "`" + `, ` + "`" + `value` + "`" + `, and ` + "`" + `q` + "`" + ` (key contains). Add ` + "`" + `include=node_pools` + "`" + ` to include linked node groups.","consumes":["application/json"],"produces":["application/json"],"tags":["Labels"],"summary":"List node labels (org scoped)","operationId":"ListLabels","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Exact key","name":"key","in":"query"},{"type":"string","description":"Exact value","name":"value","in":"query"},{"type":"string","description":"Key contains (case-insensitive)","name":"q","in":"query"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.LabelResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list node taints","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Creates a label.","consumes":["application/json"],"produces":["application/json"],"tags":["Labels"],"summary":"Create label (org scoped)","operationId":"CreateLabel","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Label payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateLabelRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.LabelResponse"}},"400":{"description":"invalid json / missing fields / invalid node_pool_ids","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"create failed","schema":{"type":"string"}}}}},"/labels/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns one label.","consumes":["application/json"],"produces":["application/json"],"tags":["Labels"],"summary":"Get label by ID (org scoped)","operationId":"GetLabel","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Label ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.LabelResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes the label.","consumes":["application/json"],"produces":["application/json"],"tags":["Labels"],"summary":"Delete label (org scoped)","operationId":"DeleteLabel","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Label ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}},"patch":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Partially update label fields.","consumes":["application/json"],"produces":["application/json"],"tags":["Labels"],"summary":"Update label (org scoped)","operationId":"UpdateLabel","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Label ID (UUID)","name":"id","in":"path","required":true},{"description":"Fields to update","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.UpdateLabelRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.LabelResponse"}},"400":{"description":"invalid id / invalid json","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"update failed","schema":{"type":"string"}}}}},"/me":{"get":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"produces":["application/json"],"tags":["Me"],"summary":"Get current user profile","operationId":"GetMe","responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/handlers.meResponse"}}}},"patch":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Me"],"summary":"Update current user profile","operationId":"UpdateMe","parameters":[{"description":"Patch profile","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.updateMeRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/models.User"}}}}},"/me/api-keys":{"get":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"produces":["application/json"],"tags":["MeAPIKeys"],"summary":"List my API keys","operationId":"ListUserAPIKeys","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/handlers.userAPIKeyOut"}}}}},"post":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"description":"Returns the plaintext key once. Store it securely on the client side.","consumes":["application/json"],"produces":["application/json"],"tags":["MeAPIKeys"],"summary":"Create a new user API key","operationId":"CreateUserAPIKey","parameters":[{"description":"Key options","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.createUserKeyRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/handlers.userAPIKeyOut"}}}}},"/me/api-keys/{id}":{"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["MeAPIKeys"],"summary":"Delete a user API key","operationId":"DeleteUserAPIKey","parameters":[{"type":"string","description":"Key ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content"}}}},"/orgs":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"List organizations I belong to","operationId":"listMyOrgs","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/models.Organization"}}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"post":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Create organization","operationId":"createOrg","parameters":[{"description":"Org payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.orgCreateReq"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/models.Organization"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"409":{"description":"Conflict","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Get organization","operationId":"getOrg","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/models.Organization"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Delete organization (owner)","operationId":"deleteOrg","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"patch":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Update organization (owner/admin)","operationId":"updateOrg","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"description":"Update payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.orgUpdateReq"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/models.Organization"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/api-keys":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"List org-scoped API keys (no secrets)","operationId":"listOrgKeys","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/models.APIKey"}}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"post":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Create org key/secret pair (owner/admin)","operationId":"createOrgKey","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"description":"Key name + optional expiry","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.orgKeyCreateReq"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/handlers.orgKeyCreateResp"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/api-keys/{key_id}":{"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Delete org key (owner/admin)","operationId":"deleteOrgKey","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"type":"string","description":"Key ID (UUID)","name":"key_id","in":"path","required":true}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/members":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"List members in org","operationId":"listMembers","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/handlers.memberOut"}}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"post":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Add or update a member (owner/admin)","operationId":"addOrUpdateMember","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"description":"User \u0026 role","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.memberUpsertReq"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/handlers.memberOut"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/members/{user_id}":{"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Remove a member (owner/admin)","operationId":"removeMember","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"type":"string","description":"User ID (UUID)","name":"user_id","in":"path","required":true}],"responses":{"204":{"description":"Removed"},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/servers":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns servers for the organization in X-Org-ID. Optional filters: status, role.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"List servers (org scoped)","operationId":"ListServers","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Filter by status (pending|provisioning|ready|failed)","name":"status","in":"query"},{"type":"string","description":"Filter by role","name":"role","in":"query"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.ServerResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list servers","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Creates a server bound to the org in X-Org-ID. Validates that ssh_key_id belongs to the org.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Create server (org scoped)","operationId":"CreateServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Server payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateServerRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.ServerResponse"}},"400":{"description":"invalid json / missing fields / invalid status / invalid ssh_key_id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"create failed","schema":{"type":"string"}}}}},"/servers/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns one server in the given organization.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Get server by ID (org scoped)","operationId":"GetServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Server ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.ServerResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes the server.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Delete server (org scoped)","operationId":"DeleteServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Server ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}},"patch":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Partially update fields; changing ssh_key_id validates ownership.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Update server (org scoped)","operationId":"UpdateServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Server ID (UUID)","name":"id","in":"path","required":true},{"description":"Fields to update","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.UpdateServerRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.ServerResponse"}},"400":{"description":"invalid id / invalid json / invalid status / invalid ssh_key_id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"update failed","schema":{"type":"string"}}}}},"/ssh":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns ssh keys for the organization in X-Org-ID.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"List ssh keys (org scoped)","operationId":"ListPublicSshKeys","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.SshResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list keys","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Generates an RSA or ED25519 keypair, saves it, and returns metadata. For RSA you may set bits (2048/3072/4096). Default is 4096. ED25519 ignores bits.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"Create ssh keypair (org scoped)","operationId":"CreateSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Key generation options","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateSSHRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.SshResponse"}},"400":{"description":"invalid json / invalid bits","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"generation/create failed","schema":{"type":"string"}}}}},"/ssh/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns public key fields. Append ` + "`" + `?reveal=true` + "`" + ` to include the private key PEM.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"Get ssh key by ID (org scoped)","operationId":"GetSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"SSH Key ID (UUID)","name":"id","in":"path","required":true},{"type":"boolean","description":"Reveal private key PEM","name":"reveal","in":"query"}],"responses":{"200":{"description":"When reveal=true","schema":{"$ref":"#/definitions/dto.SshRevealResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes a keypair.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"Delete ssh keypair (org scoped)","operationId":"DeleteSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"SSH Key ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}}},"/ssh/{id}/download":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Download ` + "`" + `part=public|private|both` + "`" + ` of the keypair. ` + "`" + `both` + "`" + ` returns a zip file.","produces":["application/json"],"tags":["Ssh"],"summary":"Download ssh key files by ID (org scoped)","operationId":"DownloadSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header","required":true},{"type":"string","description":"SSH Key ID (UUID)","name":"id","in":"path","required":true},{"enum":["public","private","both"],"type":"string","description":"Which part to download","name":"part","in":"query","required":true}],"responses":{"200":{"description":"file content","schema":{"type":"string"}},"400":{"description":"invalid id / invalid part","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"download failed","schema":{"type":"string"}}}}},"/taints":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns node taints for the organization in X-Org-ID. Filters: ` + "`" + `key` + "`" + `, ` + "`" + `value` + "`" + `, and ` + "`" + `q` + "`" + ` (key contains). Add ` + "`" + `include=node_pools` + "`" + ` to include linked node pools.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"List node pool taints (org scoped)","operationId":"ListTaints","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Exact key","name":"key","in":"query"},{"type":"string","description":"Exact value","name":"value","in":"query"},{"type":"string","description":"key contains (case-insensitive)","name":"q","in":"query"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.TaintResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list node taints","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Creates a taint.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Create node taint (org scoped)","operationId":"CreateTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Taint payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateTaintRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.TaintResponse"}},"400":{"description":"invalid json / missing fields / invalid node_pool_ids","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"create failed","schema":{"type":"string"}}}}},"/taints/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Get node taint by ID (org scoped)","operationId":"GetTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Node Taint ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TaintResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes the taint.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Delete taint (org scoped)","operationId":"DeleteTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Node Taint ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}},"patch":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Partially update taint fields.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Update node taint (org scoped)","operationId":"UpdateTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Node Taint ID (UUID)","name":"id","in":"path","required":true},{"description":"Fields to update","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.UpdateTaintRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TaintResponse"}},"400":{"description":"invalid id / invalid json","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"update failed","schema":{"type":"string"}}}}}},"definitions":{"dto.AnnotationResponse":{"type":"object","properties":{"created_at":{"type":"string"},"id":{"type":"string"},"key":{"type":"string"},"organization_id":{"type":"string"},"updated_at":{"type":"string"},"value":{"type":"string"}}},"dto.AuthStartResponse":{"type":"object","properties":{"auth_url":{"type":"string","example":"https://accounts.google.com/o/oauth2/v2/auth?client_id=..."}}},"dto.CreateAnnotationRequest":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}},"dto.CreateLabelRequest":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}},"dto.CreateSSHRequest":{"type":"object","properties":{"bits":{"description":"Only for RSA","type":"integer"},"comment":{"type":"string","example":"deploy@autoglue"},"name":{"type":"string"},"type":{"description":"\"rsa\" (default) or \"ed25519\"","type":"string"}}},"dto.CreateServerRequest":{"type":"object","properties":{"hostname":{"type":"string"},"private_ip_address":{"type":"string"},"public_ip_address":{"type":"string"},"role":{"type":"string","example":"master|worker|bastion"},"ssh_key_id":{"type":"string"},"ssh_user":{"type":"string"},"status":{"type":"string","example":"pending|provisioning|ready|failed"}}},"dto.CreateTaintRequest":{"type":"object","properties":{"effect":{"type":"string"},"key":{"type":"string"},"value":{"type":"string"}}},"dto.EnqueueRequest":{"type":"object"},"dto.JWK":{"type":"object","properties":{"alg":{"type":"string","example":"RS256"},"e":{"type":"string","example":"AQAB"},"kid":{"type":"string","example":"7c6f1d0a-7a98-4e6a-9dbf-6b1af4b9f345"},"kty":{"type":"string","example":"RSA"},"n":{"type":"string"},"use":{"type":"string","example":"sig"},"x":{"type":"string"}}},"dto.JWKS":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/definitions/dto.JWK"}}}},"dto.Job":{"type":"object","properties":{"attempts":{"type":"integer","example":0},"created_at":{"type":"string","example":"2025-11-04T09:30:00Z"},"id":{"type":"string","example":"01HF7SZK8Z8WG1M3J7S2Z8M2N6"},"last_error":{"type":"string","example":"error message"},"max_attempts":{"type":"integer","example":3},"payload":{},"queue":{"type":"string","example":"default"},"run_at":{"type":"string","example":"2025-11-04T09:30:00Z"},"status":{"enum":["queued|running|succeeded|failed|canceled|retrying|scheduled"],"allOf":[{"$ref":"#/definitions/dto.JobStatus"}],"example":"queued"},"type":{"type":"string","example":"email.send"},"updated_at":{"type":"string","example":"2025-11-04T09:30:00Z"}}},"dto.JobStatus":{"type":"string","enum":["queued","running","succeeded","failed","canceled","retrying","scheduled"],"x-enum-varnames":["StatusQueued","StatusRunning","StatusSucceeded","StatusFailed","StatusCanceled","StatusRetrying","StatusScheduled"]},"dto.LabelResponse":{"type":"object","properties":{"created_at":{"type":"string"},"id":{"type":"string"},"key":{"type":"string"},"organization_id":{"type":"string"},"updated_at":{"type":"string"},"value":{"type":"string"}}},"dto.LogoutRequest":{"type":"object","properties":{"refresh_token":{"type":"string","example":"m0l9o8rT3t0V8d3eFf..."}}},"dto.PageJob":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/definitions/dto.Job"}},"page":{"type":"integer","example":1},"page_size":{"type":"integer","example":25},"total":{"type":"integer","example":120}}},"dto.QueueInfo":{"type":"object","properties":{"failed":{"type":"integer","example":5},"name":{"type":"string","example":"default"},"pending":{"type":"integer","example":42},"running":{"type":"integer","example":3},"scheduled":{"type":"integer","example":7}}},"dto.RefreshRequest":{"type":"object","properties":{"refresh_token":{"type":"string","example":"m0l9o8rT3t0V8d3eFf..."}}},"dto.ServerResponse":{"type":"object","properties":{"created_at":{"type":"string"},"hostname":{"type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"private_ip_address":{"type":"string"},"public_ip_address":{"type":"string"},"role":{"type":"string"},"ssh_key_id":{"type":"string"},"ssh_user":{"type":"string"},"status":{"type":"string"},"updated_at":{"type":"string"}}},"dto.SshResponse":{"type":"object","properties":{"created_at":{"type":"string"},"fingerprint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"organization_id":{"type":"string"},"public_key":{"type":"string"},"updated_at":{"type":"string"}}},"dto.SshRevealResponse":{"type":"object","properties":{"created_at":{"type":"string"},"fingerprint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"organization_id":{"type":"string"},"private_key":{"type":"string"},"public_key":{"type":"string"},"updated_at":{"type":"string"}}},"dto.TaintResponse":{"type":"object","properties":{"created_at":{"type":"string"},"effect":{"type":"string"},"id":{"type":"string"},"key":{"type":"string"},"organization_id":{"type":"string"},"updated_at":{"type":"string"},"value":{"type":"string"}}},"dto.TokenPair":{"type":"object","properties":{"access_token":{"type":"string","example":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ij..."},"expires_in":{"type":"integer","example":3600},"refresh_token":{"type":"string","example":"m0l9o8rT3t0V8d3eFf...."},"token_type":{"type":"string","example":"Bearer"}}},"dto.UpdateAnnotationRequest":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}},"dto.UpdateLabelRequest":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}},"dto.UpdateServerRequest":{"type":"object","properties":{"hostname":{"type":"string"},"private_ip_address":{"type":"string"},"public_ip_address":{"type":"string"},"role":{"type":"string","example":"master|worker|bastion"},"ssh_key_id":{"type":"string"},"ssh_user":{"type":"string"},"status":{"type":"string","example":"pending|provisioning|ready|failed"}}},"dto.UpdateTaintRequest":{"type":"object","properties":{"effect":{"type":"string"},"key":{"type":"string"},"value":{"type":"string"}}},"handlers.HealthStatus":{"type":"object","properties":{"status":{"type":"string","example":"ok"}}},"handlers.createUserKeyRequest":{"type":"object","properties":{"expires_in_hours":{"description":"optional TTL","type":"integer"},"name":{"type":"string"}}},"handlers.meResponse":{"type":"object","properties":{"avatar_url":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"display_name":{"type":"string"},"emails":{"type":"array","items":{"$ref":"#/definitions/models.UserEmail"}},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"is_admin":{"type":"boolean"},"is_disabled":{"type":"boolean"},"organizations":{"type":"array","items":{"$ref":"#/definitions/models.Organization"}},"primary_email":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"handlers.memberOut":{"type":"object","properties":{"email":{"type":"string"},"role":{"description":"owner/admin/member","type":"string"},"user_id":{"type":"string","format":"uuid"}}},"handlers.memberUpsertReq":{"type":"object","properties":{"role":{"type":"string","example":"member"},"user_id":{"type":"string","format":"uuid"}}},"handlers.orgCreateReq":{"type":"object","properties":{"domain":{"type":"string","example":"acme.com"},"name":{"type":"string","example":"Acme Corp"}}},"handlers.orgKeyCreateReq":{"type":"object","properties":{"expires_in_hours":{"type":"integer","example":720},"name":{"type":"string","example":"automation-bot"}}},"handlers.orgKeyCreateResp":{"type":"object","properties":{"created_at":{"type":"string"},"expires_at":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"org_key":{"description":"shown once:","type":"string"},"org_secret":{"description":"shown once:","type":"string"},"scope":{"description":"\"org\"","type":"string"}}},"handlers.orgUpdateReq":{"type":"object","properties":{"domain":{"type":"string"},"name":{"type":"string"}}},"handlers.updateMeRequest":{"type":"object","properties":{"display_name":{"type":"string"}}},"handlers.userAPIKeyOut":{"type":"object","properties":{"created_at":{"type":"string"},"expires_at":{"type":"string"},"id":{"type":"string","format":"uuid"},"last_used_at":{"type":"string"},"name":{"type":"string"},"plain":{"description":"Shown only on create:","type":"string"},"scope":{"description":"\"user\"","type":"string"}}},"models.APIKey":{"type":"object","properties":{"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"id":{"type":"string","format":"uuid"},"last_used_at":{"type":"string","format":"date-time"},"name":{"type":"string"},"org_id":{"type":"string","format":"uuid"},"prefix":{"type":"string"},"revoked":{"type":"boolean"},"scope":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"user_id":{"type":"string","format":"uuid"}}},"models.Organization":{"type":"object","properties":{"created_at":{"type":"string","format":"date-time"},"domain":{"type":"string"},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"name":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"models.User":{"type":"object","properties":{"avatar_url":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"display_name":{"type":"string"},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"is_admin":{"type":"boolean"},"is_disabled":{"type":"boolean"},"primary_email":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"models.UserEmail":{"type":"object","properties":{"created_at":{"type":"string","format":"date-time"},"email":{"type":"string"},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"is_primary":{"type":"boolean"},"is_verified":{"type":"boolean"},"updated_at":{"type":"string","format":"date-time"},"user":{"$ref":"#/definitions/models.User"},"user_id":{"type":"string","format":"uuid"}}},"utils.ErrorResponse":{"type":"object","properties":{"code":{"description":"A machine-readable error code, e.g. \"validation_error\"\nexample: validation_error","type":"string"},"message":{"description":"Human-readable message\nexample: slug is required","type":"string"}}}},"securityDefinitions":{"ApiKeyAuth":{"description":"User API key","type":"apiKey","name":"X-API-KEY","in":"header"},"BearerAuth":{"description":"Bearer token authentication","type":"apiKey","name":"Authorization","in":"header"},"OrgKeyAuth":{"description":"Org-level key/secret authentication","type":"apiKey","name":"X-ORG-KEY","in":"header"},"OrgSecretAuth":{"description":"Org-level secret","type":"apiKey","name":"X-ORG-SECRET","in":"header"}}}` + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "contact": { + "name": "GlueOps" + }, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/.well-known/jwks.json": { + "get": { + "description": "Returns the JSON Web Key Set for token verification", + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "summary": "Get JWKS", + "operationId": "getJWKS", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.JWKS" + } + } + } + } + }, + "/admin/archer/jobs": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Paginated background jobs with optional filters. Search ` + "`" + `q` + "`" + ` may match id, type, error, payload (implementation-dependent).", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ArcherAdmin" + ], + "summary": "List Archer jobs (admin)", + "operationId": "AdminListArcherJobs", + "parameters": [ + { + "enum": [ + "queued", + "running", + "succeeded", + "failed", + "canceled", + "retrying", + "scheduled" + ], + "type": "string", + "description": "Filter by status", + "name": "status", + "in": "query" + }, + { + "type": "string", + "description": "Filter by queue name / worker name", + "name": "queue", + "in": "query" + }, + { + "type": "string", + "description": "Free-text search", + "name": "q", + "in": "query" + }, + { + "type": "integer", + "default": 1, + "description": "Page number", + "name": "page", + "in": "query" + }, + { + "maximum": 100, + "minimum": 1, + "type": "integer", + "default": 25, + "description": "Items per page", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.PageJob" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "forbidden", + "schema": { + "type": "string" + } + }, + "500": { + "description": "internal error", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Create a job immediately or schedule it for the future via ` + "`" + `run_at` + "`" + `.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ArcherAdmin" + ], + "summary": "Enqueue a new Archer job (admin)", + "operationId": "AdminEnqueueArcherJob", + "parameters": [ + { + "description": "Job parameters", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.EnqueueRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.Job" + } + }, + "400": { + "description": "invalid json or missing fields", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "forbidden", + "schema": { + "type": "string" + } + }, + "500": { + "description": "internal error", + "schema": { + "type": "string" + } + } + } + } + }, + "/admin/archer/jobs/{id}/cancel": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Set job status to canceled if cancellable. For running jobs, this only affects future picks; wire to Archer if you need active kill.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ArcherAdmin" + ], + "summary": "Cancel an Archer job (admin)", + "operationId": "AdminCancelArcherJob", + "parameters": [ + { + "type": "string", + "description": "Job ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.Job" + } + }, + "400": { + "description": "invalid job or not cancellable", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "forbidden", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + } + } + } + }, + "/admin/archer/jobs/{id}/retry": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Marks the job retriable (DB flip). Swap this for an Archer admin call if you expose one.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ArcherAdmin" + ], + "summary": "Retry a failed/canceled Archer job (admin)", + "operationId": "AdminRetryArcherJob", + "parameters": [ + { + "type": "string", + "description": "Job ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.Job" + } + }, + "400": { + "description": "invalid job or not eligible", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "forbidden", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + } + } + } + }, + "/admin/archer/queues": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Summary metrics per queue (pending, running, failed, scheduled).", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ArcherAdmin" + ], + "summary": "List Archer queues (admin)", + "operationId": "AdminListArcherQueues", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.QueueInfo" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "forbidden", + "schema": { + "type": "string" + } + }, + "500": { + "description": "internal error", + "schema": { + "type": "string" + } + } + } + } + }, + "/annotations": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns annotations for the organization in X-Org-ID. Filters: ` + "`" + `key` + "`" + `, ` + "`" + `value` + "`" + `, and ` + "`" + `q` + "`" + ` (key contains). Add ` + "`" + `include=node_pools` + "`" + ` to include linked node pools.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Annotations" + ], + "summary": "List annotations (org scoped)", + "operationId": "ListAnnotations", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Exact key", + "name": "key", + "in": "query" + }, + { + "type": "string", + "description": "Exact value", + "name": "value", + "in": "query" + }, + { + "type": "string", + "description": "key contains (case-insensitive)", + "name": "q", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.AnnotationResponse" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "failed to list annotations", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Creates an annotation.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Annotations" + ], + "summary": "Create annotation (org scoped)", + "operationId": "CreateAnnotation", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "description": "Annotation payload", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.CreateAnnotationRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.AnnotationResponse" + } + }, + "400": { + "description": "invalid json / missing fields", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "create failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/annotations/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns one annotation. Add ` + "`" + `include=node_pools` + "`" + ` to include node pools.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Annotations" + ], + "summary": "Get annotation by ID (org scoped)", + "operationId": "GetAnnotation", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Annotation ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.AnnotationResponse" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "fetch failed", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Permanently deletes the annotation.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Annotations" + ], + "summary": "Delete annotation (org scoped)", + "operationId": "DeleteAnnotation", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Annotation ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "delete failed", + "schema": { + "type": "string" + } + } + } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Partially update annotation fields.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Annotations" + ], + "summary": "Update annotation (org scoped)", + "operationId": "UpdateAnnotation", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Annotation ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Fields to update", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UpdateAnnotationRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.AnnotationResponse" + } + }, + "400": { + "description": "invalid id / invalid json", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "update failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/auth/logout": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "summary": "Revoke refresh token family (logout everywhere)", + "operationId": "Logout", + "parameters": [ + { + "description": "Refresh token", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.LogoutRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/auth/refresh": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "summary": "Rotate refresh token", + "operationId": "Refresh", + "parameters": [ + { + "description": "Refresh token", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.RefreshRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.TokenPair" + } + } + } + } + }, + "/auth/{provider}/callback": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "summary": "Handle social login callback", + "operationId": "AuthCallback", + "parameters": [ + { + "type": "string", + "description": "google|github", + "name": "provider", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.TokenPair" + } + } + } + } + }, + "/auth/{provider}/start": { + "post": { + "description": "Returns provider authorization URL for the frontend to redirect", + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "summary": "Begin social login", + "operationId": "AuthStart", + "parameters": [ + { + "type": "string", + "description": "google|github", + "name": "provider", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.AuthStartResponse" + } + } + } + } + }, + "/healthz": { + "get": { + "description": "Returns 200 OK when the service is up", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Health" + ], + "summary": "Basic health check", + "operationId": "HealthCheck // operationId", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.HealthStatus" + } + } + } + } + }, + "/labels": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns node labels for the organization in X-Org-ID. Filters: ` + "`" + `key` + "`" + `, ` + "`" + `value` + "`" + `, and ` + "`" + `q` + "`" + ` (key contains). Add ` + "`" + `include=node_pools` + "`" + ` to include linked node groups.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "List node labels (org scoped)", + "operationId": "ListLabels", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Exact key", + "name": "key", + "in": "query" + }, + { + "type": "string", + "description": "Exact value", + "name": "value", + "in": "query" + }, + { + "type": "string", + "description": "Key contains (case-insensitive)", + "name": "q", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.LabelResponse" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "failed to list node taints", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Creates a label.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "Create label (org scoped)", + "operationId": "CreateLabel", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "description": "Label payload", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.CreateLabelRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.LabelResponse" + } + }, + "400": { + "description": "invalid json / missing fields / invalid node_pool_ids", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "create failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/labels/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns one label.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "Get label by ID (org scoped)", + "operationId": "GetLabel", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Label ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.LabelResponse" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "fetch failed", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Permanently deletes the label.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "Delete label (org scoped)", + "operationId": "DeleteLabel", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Label ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "delete failed", + "schema": { + "type": "string" + } + } + } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Partially update label fields.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "Update label (org scoped)", + "operationId": "UpdateLabel", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Label ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Fields to update", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UpdateLabelRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.LabelResponse" + } + }, + "400": { + "description": "invalid id / invalid json", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "update failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/me": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "ApiKeyAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Me" + ], + "summary": "Get current user profile", + "operationId": "GetMe", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.meResponse" + } + } + } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + }, + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Me" + ], + "summary": "Update current user profile", + "operationId": "UpdateMe", + "parameters": [ + { + "description": "Patch profile", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.updateMeRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.User" + } + } + } + } + }, + "/me/api-keys": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "ApiKeyAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "MeAPIKeys" + ], + "summary": "List my API keys", + "operationId": "ListUserAPIKeys", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/handlers.userAPIKeyOut" + } + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + }, + { + "ApiKeyAuth": [] + } + ], + "description": "Returns the plaintext key once. Store it securely on the client side.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "MeAPIKeys" + ], + "summary": "Create a new user API key", + "operationId": "CreateUserAPIKey", + "parameters": [ + { + "description": "Key options", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.createUserKeyRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/handlers.userAPIKeyOut" + } + } + } + } + }, + "/me/api-keys/{id}": { + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "MeAPIKeys" + ], + "summary": "Delete a user API key", + "operationId": "DeleteUserAPIKey", + "parameters": [ + { + "type": "string", + "description": "Key ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/orgs": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "List organizations I belong to", + "operationId": "listMyOrgs", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Organization" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Create organization", + "operationId": "createOrg", + "parameters": [ + { + "description": "Org payload", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.orgCreateReq" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/models.Organization" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + }, + "409": { + "description": "Conflict", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + } + }, + "/orgs/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Get organization", + "operationId": "getOrg", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.Organization" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Delete organization (owner)", + "operationId": "deleteOrg", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "Deleted" + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Update organization (owner/admin)", + "operationId": "updateOrg", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Update payload", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.orgUpdateReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.Organization" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + } + }, + "/orgs/{id}/api-keys": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "List org-scoped API keys (no secrets)", + "operationId": "listOrgKeys", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.APIKey" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Create org key/secret pair (owner/admin)", + "operationId": "createOrgKey", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Key name + optional expiry", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.orgKeyCreateReq" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/handlers.orgKeyCreateResp" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + } + }, + "/orgs/{id}/api-keys/{key_id}": { + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Delete org key (owner/admin)", + "operationId": "deleteOrgKey", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Key ID (UUID)", + "name": "key_id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "Deleted" + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + } + }, + "/orgs/{id}/members": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "List members in org", + "operationId": "listMembers", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/handlers.memberOut" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Add or update a member (owner/admin)", + "operationId": "addOrUpdateMember", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "User \u0026 role", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.memberUpsertReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.memberOut" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + } + }, + "/orgs/{id}/members/{user_id}": { + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Remove a member (owner/admin)", + "operationId": "removeMember", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "User ID (UUID)", + "name": "user_id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "Removed" + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + } + }, + "/servers": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns servers for the organization in X-Org-ID. Optional filters: status, role.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Servers" + ], + "summary": "List servers (org scoped)", + "operationId": "ListServers", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Filter by status (pending|provisioning|ready|failed)", + "name": "status", + "in": "query" + }, + { + "type": "string", + "description": "Filter by role", + "name": "role", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.ServerResponse" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "failed to list servers", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Creates a server bound to the org in X-Org-ID. Validates that ssh_key_id belongs to the org.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Servers" + ], + "summary": "Create server (org scoped)", + "operationId": "CreateServer", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "description": "Server payload", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.CreateServerRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.ServerResponse" + } + }, + "400": { + "description": "invalid json / missing fields / invalid status / invalid ssh_key_id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "create failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/servers/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns one server in the given organization.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Servers" + ], + "summary": "Get server by ID (org scoped)", + "operationId": "GetServer", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Server ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.ServerResponse" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "fetch failed", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Permanently deletes the server.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Servers" + ], + "summary": "Delete server (org scoped)", + "operationId": "DeleteServer", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Server ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "delete failed", + "schema": { + "type": "string" + } + } + } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Partially update fields; changing ssh_key_id validates ownership.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Servers" + ], + "summary": "Update server (org scoped)", + "operationId": "UpdateServer", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Server ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Fields to update", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UpdateServerRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.ServerResponse" + } + }, + "400": { + "description": "invalid id / invalid json / invalid status / invalid ssh_key_id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "update failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/ssh": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns ssh keys for the organization in X-Org-ID.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Ssh" + ], + "summary": "List ssh keys (org scoped)", + "operationId": "ListPublicSshKeys", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.SshResponse" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "failed to list keys", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Generates an RSA or ED25519 keypair, saves it, and returns metadata. For RSA you may set bits (2048/3072/4096). Default is 4096. ED25519 ignores bits.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Ssh" + ], + "summary": "Create ssh keypair (org scoped)", + "operationId": "CreateSSHKey", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "description": "Key generation options", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.CreateSSHRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.SshResponse" + } + }, + "400": { + "description": "invalid json / invalid bits", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "generation/create failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/ssh/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns public key fields. Append ` + "`" + `?reveal=true` + "`" + ` to include the private key PEM.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Ssh" + ], + "summary": "Get ssh key by ID (org scoped)", + "operationId": "GetSSHKey", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "SSH Key ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Reveal private key PEM", + "name": "reveal", + "in": "query" + } + ], + "responses": { + "200": { + "description": "When reveal=true", + "schema": { + "$ref": "#/definitions/dto.SshRevealResponse" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "fetch failed", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Permanently deletes a keypair.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Ssh" + ], + "summary": "Delete ssh keypair (org scoped)", + "operationId": "DeleteSSHKey", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "SSH Key ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "delete failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/ssh/{id}/download": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Download ` + "`" + `part=public|private|both` + "`" + ` of the keypair. ` + "`" + `both` + "`" + ` returns a zip file.", + "produces": [ + "application/json" + ], + "tags": [ + "Ssh" + ], + "summary": "Download ssh key files by ID (org scoped)", + "operationId": "DownloadSSHKey", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "SSH Key ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "enum": [ + "public", + "private", + "both" + ], + "type": "string", + "description": "Which part to download", + "name": "part", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "file content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "invalid id / invalid part", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "download failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/taints": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns node taints for the organization in X-Org-ID. Filters: ` + "`" + `key` + "`" + `, ` + "`" + `value` + "`" + `, and ` + "`" + `q` + "`" + ` (key contains). Add ` + "`" + `include=node_pools` + "`" + ` to include linked node pools.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Taints" + ], + "summary": "List node pool taints (org scoped)", + "operationId": "ListTaints", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Exact key", + "name": "key", + "in": "query" + }, + { + "type": "string", + "description": "Exact value", + "name": "value", + "in": "query" + }, + { + "type": "string", + "description": "key contains (case-insensitive)", + "name": "q", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.TaintResponse" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "failed to list node taints", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Creates a taint.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Taints" + ], + "summary": "Create node taint (org scoped)", + "operationId": "CreateTaint", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "description": "Taint payload", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.CreateTaintRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.TaintResponse" + } + }, + "400": { + "description": "invalid json / missing fields / invalid node_pool_ids", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "create failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/taints/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Taints" + ], + "summary": "Get node taint by ID (org scoped)", + "operationId": "GetTaint", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Node Taint ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.TaintResponse" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "fetch failed", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Permanently deletes the taint.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Taints" + ], + "summary": "Delete taint (org scoped)", + "operationId": "DeleteTaint", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Node Taint ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "delete failed", + "schema": { + "type": "string" + } + } + } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Partially update taint fields.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Taints" + ], + "summary": "Update node taint (org scoped)", + "operationId": "UpdateTaint", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Node Taint ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Fields to update", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UpdateTaintRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.TaintResponse" + } + }, + "400": { + "description": "invalid id / invalid json", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "update failed", + "schema": { + "type": "string" + } + } + } + } + } + }, + "definitions": { + "dto.AnnotationResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "key": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.AuthStartResponse": { + "type": "object", + "properties": { + "auth_url": { + "type": "string", + "example": "https://accounts.google.com/o/oauth2/v2/auth?client_id=..." + } + } + }, + "dto.CreateAnnotationRequest": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.CreateLabelRequest": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.CreateSSHRequest": { + "type": "object", + "properties": { + "bits": { + "description": "Only for RSA", + "type": "integer" + }, + "comment": { + "type": "string", + "example": "deploy@autoglue" + }, + "name": { + "type": "string" + }, + "type": { + "description": "\"rsa\" (default) or \"ed25519\"", + "type": "string" + } + } + }, + "dto.CreateServerRequest": { + "type": "object", + "properties": { + "hostname": { + "type": "string" + }, + "private_ip_address": { + "type": "string" + }, + "public_ip_address": { + "type": "string" + }, + "role": { + "type": "string", + "example": "master|worker|bastion" + }, + "ssh_key_id": { + "type": "string" + }, + "ssh_user": { + "type": "string" + }, + "status": { + "type": "string", + "example": "pending|provisioning|ready|failed" + } + } + }, + "dto.CreateTaintRequest": { + "type": "object", + "properties": { + "effect": { + "type": "string" + }, + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.EnqueueRequest": { + "type": "object" + }, + "dto.JWK": { + "type": "object", + "properties": { + "alg": { + "type": "string", + "example": "RS256" + }, + "e": { + "type": "string", + "example": "AQAB" + }, + "kid": { + "type": "string", + "example": "7c6f1d0a-7a98-4e6a-9dbf-6b1af4b9f345" + }, + "kty": { + "type": "string", + "example": "RSA" + }, + "n": { + "type": "string" + }, + "use": { + "type": "string", + "example": "sig" + }, + "x": { + "type": "string" + } + } + }, + "dto.JWKS": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.JWK" + } + } + } + }, + "dto.Job": { + "type": "object", + "properties": { + "attempts": { + "type": "integer", + "example": 0 + }, + "created_at": { + "type": "string", + "example": "2025-11-04T09:30:00Z" + }, + "id": { + "type": "string", + "example": "01HF7SZK8Z8WG1M3J7S2Z8M2N6" + }, + "last_error": { + "type": "string", + "example": "error message" + }, + "max_attempts": { + "type": "integer", + "example": 3 + }, + "payload": {}, + "queue": { + "type": "string", + "example": "default" + }, + "run_at": { + "type": "string", + "example": "2025-11-04T09:30:00Z" + }, + "status": { + "enum": [ + "queued|running|succeeded|failed|canceled|retrying|scheduled" + ], + "allOf": [ + { + "$ref": "#/definitions/dto.JobStatus" + } + ], + "example": "queued" + }, + "type": { + "type": "string", + "example": "email.send" + }, + "updated_at": { + "type": "string", + "example": "2025-11-04T09:30:00Z" + } + } + }, + "dto.JobStatus": { + "type": "string", + "enum": [ + "queued", + "running", + "succeeded", + "failed", + "canceled", + "retrying", + "scheduled" + ], + "x-enum-varnames": [ + "StatusQueued", + "StatusRunning", + "StatusSucceeded", + "StatusFailed", + "StatusCanceled", + "StatusRetrying", + "StatusScheduled" + ] + }, + "dto.LabelResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "key": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.LogoutRequest": { + "type": "object", + "properties": { + "refresh_token": { + "type": "string", + "example": "m0l9o8rT3t0V8d3eFf..." + } + } + }, + "dto.PageJob": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.Job" + } + }, + "page": { + "type": "integer", + "example": 1 + }, + "page_size": { + "type": "integer", + "example": 25 + }, + "total": { + "type": "integer", + "example": 120 + } + } + }, + "dto.QueueInfo": { + "type": "object", + "properties": { + "failed": { + "type": "integer", + "example": 5 + }, + "name": { + "type": "string", + "example": "default" + }, + "pending": { + "type": "integer", + "example": 42 + }, + "running": { + "type": "integer", + "example": 3 + }, + "scheduled": { + "type": "integer", + "example": 7 + } + } + }, + "dto.RefreshRequest": { + "type": "object", + "properties": { + "refresh_token": { + "type": "string", + "example": "m0l9o8rT3t0V8d3eFf..." + } + } + }, + "dto.ServerResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "hostname": { + "type": "string" + }, + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "private_ip_address": { + "type": "string" + }, + "public_ip_address": { + "type": "string" + }, + "role": { + "type": "string" + }, + "ssh_key_id": { + "type": "string" + }, + "ssh_user": { + "type": "string" + }, + "status": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "dto.SshResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "fingerprint": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "public_key": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "dto.SshRevealResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "fingerprint": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "private_key": { + "type": "string" + }, + "public_key": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "dto.TaintResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "effect": { + "type": "string" + }, + "id": { + "type": "string" + }, + "key": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.TokenPair": { + "type": "object", + "properties": { + "access_token": { + "type": "string", + "example": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ij..." + }, + "expires_in": { + "type": "integer", + "example": 3600 + }, + "refresh_token": { + "type": "string", + "example": "m0l9o8rT3t0V8d3eFf...." + }, + "token_type": { + "type": "string", + "example": "Bearer" + } + } + }, + "dto.UpdateAnnotationRequest": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.UpdateLabelRequest": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.UpdateServerRequest": { + "type": "object", + "properties": { + "hostname": { + "type": "string" + }, + "private_ip_address": { + "type": "string" + }, + "public_ip_address": { + "type": "string" + }, + "role": { + "type": "string", + "example": "master|worker|bastion" + }, + "ssh_key_id": { + "type": "string" + }, + "ssh_user": { + "type": "string" + }, + "status": { + "type": "string", + "example": "pending|provisioning|ready|failed" + } + } + }, + "dto.UpdateTaintRequest": { + "type": "object", + "properties": { + "effect": { + "type": "string" + }, + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "handlers.HealthStatus": { + "type": "object", + "properties": { + "status": { + "type": "string", + "example": "ok" + } + } + }, + "handlers.createUserKeyRequest": { + "type": "object", + "properties": { + "expires_in_hours": { + "description": "optional TTL", + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, + "handlers.meResponse": { + "type": "object", + "properties": { + "avatar_url": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "display_name": { + "type": "string" + }, + "emails": { + "type": "array", + "items": { + "$ref": "#/definitions/models.UserEmail" + } + }, + "id": { + "description": "example: 3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type": "string", + "format": "uuid" + }, + "is_admin": { + "type": "boolean" + }, + "is_disabled": { + "type": "boolean" + }, + "organizations": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Organization" + } + }, + "primary_email": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "handlers.memberOut": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "role": { + "description": "owner/admin/member", + "type": "string" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "handlers.memberUpsertReq": { + "type": "object", + "properties": { + "role": { + "type": "string", + "example": "member" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "handlers.orgCreateReq": { + "type": "object", + "properties": { + "domain": { + "type": "string", + "example": "acme.com" + }, + "name": { + "type": "string", + "example": "Acme Corp" + } + } + }, + "handlers.orgKeyCreateReq": { + "type": "object", + "properties": { + "expires_in_hours": { + "type": "integer", + "example": 720 + }, + "name": { + "type": "string", + "example": "automation-bot" + } + } + }, + "handlers.orgKeyCreateResp": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "expires_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "org_key": { + "description": "shown once:", + "type": "string" + }, + "org_secret": { + "description": "shown once:", + "type": "string" + }, + "scope": { + "description": "\"org\"", + "type": "string" + } + } + }, + "handlers.orgUpdateReq": { + "type": "object", + "properties": { + "domain": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "handlers.updateMeRequest": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + } + } + }, + "handlers.userAPIKeyOut": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "expires_at": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_used_at": { + "type": "string" + }, + "name": { + "type": "string" + }, + "plain": { + "description": "Shown only on create:", + "type": "string" + }, + "scope": { + "description": "\"user\"", + "type": "string" + } + } + }, + "models.APIKey": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "expires_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_used_at": { + "type": "string", + "format": "date-time" + }, + "name": { + "type": "string" + }, + "org_id": { + "type": "string", + "format": "uuid" + }, + "prefix": { + "type": "string" + }, + "revoked": { + "type": "boolean" + }, + "scope": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "models.Organization": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "domain": { + "type": "string" + }, + "id": { + "description": "example: 3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "models.User": { + "type": "object", + "properties": { + "avatar_url": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "display_name": { + "type": "string" + }, + "id": { + "description": "example: 3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type": "string", + "format": "uuid" + }, + "is_admin": { + "type": "boolean" + }, + "is_disabled": { + "type": "boolean" + }, + "primary_email": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "models.UserEmail": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "email": { + "type": "string" + }, + "id": { + "description": "example: 3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type": "string", + "format": "uuid" + }, + "is_primary": { + "type": "boolean" + }, + "is_verified": { + "type": "boolean" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user": { + "$ref": "#/definitions/models.User" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "utils.ErrorResponse": { + "type": "object", + "properties": { + "code": { + "description": "A machine-readable error code, e.g. \"validation_error\"\nexample: validation_error", + "type": "string" + }, + "message": { + "description": "Human-readable message\nexample: slug is required", + "type": "string" + } + } + } + }, + "securityDefinitions": { + "ApiKeyAuth": { + "description": "User API key", + "type": "apiKey", + "name": "X-API-KEY", + "in": "header" + }, + "BearerAuth": { + "description": "Bearer token authentication", + "type": "apiKey", + "name": "Authorization", + "in": "header" + }, + "OrgKeyAuth": { + "description": "Org-level key/secret authentication", + "type": "apiKey", + "name": "X-ORG-KEY", + "in": "header" + }, + "OrgSecretAuth": { + "description": "Org-level secret", + "type": "apiKey", + "name": "X-ORG-SECRET", + "in": "header" + } + } +}` // SwaggerInfo holds exported Swagger Info so clients can modify it var SwaggerInfo = &swag.Spec{ diff --git a/docs/swagger.json b/docs/swagger.json index b3b0a93..315f10e 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1 +1,4055 @@ -{"schemes":["http","https"],"swagger":"2.0","info":{"description":"API for managing K3s clusters across cloud providers","title":"AutoGlue API","contact":{"name":"GlueOps"},"version":"1.0"},"host":"localhost:8080","basePath":"/api/v1","paths":{"/.well-known/jwks.json":{"get":{"description":"Returns the JSON Web Key Set for token verification","produces":["application/json"],"tags":["Auth"],"summary":"Get JWKS","operationId":"getJWKS","responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.JWKS"}}}}},"/admin/archer/jobs":{"get":{"security":[{"BearerAuth":[]}],"description":"Paginated background jobs with optional filters. Search `q` may match id, type, error, payload (implementation-dependent).","consumes":["application/json"],"produces":["application/json"],"tags":["ArcherAdmin"],"summary":"List Archer jobs (admin)","operationId":"AdminListArcherJobs","parameters":[{"enum":["queued","running","succeeded","failed","canceled","retrying","scheduled"],"type":"string","description":"Filter by status","name":"status","in":"query"},{"type":"string","description":"Filter by queue name / worker name","name":"queue","in":"query"},{"type":"string","description":"Free-text search","name":"q","in":"query"},{"type":"integer","default":1,"description":"Page number","name":"page","in":"query"},{"maximum":100,"minimum":1,"type":"integer","default":25,"description":"Items per page","name":"page_size","in":"query"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.PageJob"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"forbidden","schema":{"type":"string"}},"500":{"description":"internal error","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]}],"description":"Create a job immediately or schedule it for the future via `run_at`.","consumes":["application/json"],"produces":["application/json"],"tags":["ArcherAdmin"],"summary":"Enqueue a new Archer job (admin)","operationId":"AdminEnqueueArcherJob","parameters":[{"description":"Job parameters","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.EnqueueRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.Job"}},"400":{"description":"invalid json or missing fields","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"forbidden","schema":{"type":"string"}},"500":{"description":"internal error","schema":{"type":"string"}}}}},"/admin/archer/jobs/{id}/cancel":{"post":{"security":[{"BearerAuth":[]}],"description":"Set job status to canceled if cancellable. For running jobs, this only affects future picks; wire to Archer if you need active kill.","consumes":["application/json"],"produces":["application/json"],"tags":["ArcherAdmin"],"summary":"Cancel an Archer job (admin)","operationId":"AdminCancelArcherJob","parameters":[{"type":"string","description":"Job ID","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.Job"}},"400":{"description":"invalid job or not cancellable","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"forbidden","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}}}}},"/admin/archer/jobs/{id}/retry":{"post":{"security":[{"BearerAuth":[]}],"description":"Marks the job retriable (DB flip). Swap this for an Archer admin call if you expose one.","consumes":["application/json"],"produces":["application/json"],"tags":["ArcherAdmin"],"summary":"Retry a failed/canceled Archer job (admin)","operationId":"AdminRetryArcherJob","parameters":[{"type":"string","description":"Job ID","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.Job"}},"400":{"description":"invalid job or not eligible","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"forbidden","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}}}}},"/admin/archer/queues":{"get":{"security":[{"BearerAuth":[]}],"description":"Summary metrics per queue (pending, running, failed, scheduled).","consumes":["application/json"],"produces":["application/json"],"tags":["ArcherAdmin"],"summary":"List Archer queues (admin)","operationId":"AdminListArcherQueues","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.QueueInfo"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"forbidden","schema":{"type":"string"}},"500":{"description":"internal error","schema":{"type":"string"}}}}},"/annotations":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns annotations for the organization in X-Org-ID. Filters: `key`, `value`, and `q` (key contains). Add `include=node_pools` to include linked node pools.","consumes":["application/json"],"produces":["application/json"],"tags":["Annotations"],"summary":"List annotations (org scoped)","operationId":"ListAnnotations","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Exact key","name":"key","in":"query"},{"type":"string","description":"Exact value","name":"value","in":"query"},{"type":"string","description":"key contains (case-insensitive)","name":"q","in":"query"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.AnnotationResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list annotations","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Creates an annotation.","consumes":["application/json"],"produces":["application/json"],"tags":["Annotations"],"summary":"Create annotation (org scoped)","operationId":"CreateAnnotation","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Annotation payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateAnnotationRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.AnnotationResponse"}},"400":{"description":"invalid json / missing fields","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"create failed","schema":{"type":"string"}}}}},"/annotations/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns one annotation. Add `include=node_pools` to include node pools.","consumes":["application/json"],"produces":["application/json"],"tags":["Annotations"],"summary":"Get annotation by ID (org scoped)","operationId":"GetAnnotation","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Annotation ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.AnnotationResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes the annotation.","consumes":["application/json"],"produces":["application/json"],"tags":["Annotations"],"summary":"Delete annotation (org scoped)","operationId":"DeleteAnnotation","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Annotation ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}},"patch":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Partially update annotation fields.","consumes":["application/json"],"produces":["application/json"],"tags":["Annotations"],"summary":"Update annotation (org scoped)","operationId":"UpdateAnnotation","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Annotation ID (UUID)","name":"id","in":"path","required":true},{"description":"Fields to update","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.UpdateAnnotationRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.AnnotationResponse"}},"400":{"description":"invalid id / invalid json","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"update failed","schema":{"type":"string"}}}}},"/auth/logout":{"post":{"consumes":["application/json"],"produces":["application/json"],"tags":["Auth"],"summary":"Revoke refresh token family (logout everywhere)","operationId":"Logout","parameters":[{"description":"Refresh token","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.LogoutRequest"}}],"responses":{"204":{"description":"No Content"}}}},"/auth/refresh":{"post":{"consumes":["application/json"],"produces":["application/json"],"tags":["Auth"],"summary":"Rotate refresh token","operationId":"Refresh","parameters":[{"description":"Refresh token","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.RefreshRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TokenPair"}}}}},"/auth/{provider}/callback":{"get":{"produces":["application/json"],"tags":["Auth"],"summary":"Handle social login callback","operationId":"AuthCallback","parameters":[{"type":"string","description":"google|github","name":"provider","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TokenPair"}}}}},"/auth/{provider}/start":{"post":{"description":"Returns provider authorization URL for the frontend to redirect","produces":["application/json"],"tags":["Auth"],"summary":"Begin social login","operationId":"AuthStart","parameters":[{"type":"string","description":"google|github","name":"provider","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.AuthStartResponse"}}}}},"/healthz":{"get":{"description":"Returns 200 OK when the service is up","consumes":["application/json"],"produces":["application/json"],"tags":["Health"],"summary":"Basic health check","operationId":"HealthCheck // operationId","responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/handlers.HealthStatus"}}}}},"/labels":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns node labels for the organization in X-Org-ID. Filters: `key`, `value`, and `q` (key contains). Add `include=node_pools` to include linked node groups.","consumes":["application/json"],"produces":["application/json"],"tags":["Labels"],"summary":"List node labels (org scoped)","operationId":"ListLabels","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Exact key","name":"key","in":"query"},{"type":"string","description":"Exact value","name":"value","in":"query"},{"type":"string","description":"Key contains (case-insensitive)","name":"q","in":"query"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.LabelResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list node taints","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Creates a label.","consumes":["application/json"],"produces":["application/json"],"tags":["Labels"],"summary":"Create label (org scoped)","operationId":"CreateLabel","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Label payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateLabelRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.LabelResponse"}},"400":{"description":"invalid json / missing fields / invalid node_pool_ids","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"create failed","schema":{"type":"string"}}}}},"/labels/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns one label.","consumes":["application/json"],"produces":["application/json"],"tags":["Labels"],"summary":"Get label by ID (org scoped)","operationId":"GetLabel","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Label ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.LabelResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes the label.","consumes":["application/json"],"produces":["application/json"],"tags":["Labels"],"summary":"Delete label (org scoped)","operationId":"DeleteLabel","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Label ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}},"patch":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Partially update label fields.","consumes":["application/json"],"produces":["application/json"],"tags":["Labels"],"summary":"Update label (org scoped)","operationId":"UpdateLabel","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Label ID (UUID)","name":"id","in":"path","required":true},{"description":"Fields to update","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.UpdateLabelRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.LabelResponse"}},"400":{"description":"invalid id / invalid json","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"update failed","schema":{"type":"string"}}}}},"/me":{"get":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"produces":["application/json"],"tags":["Me"],"summary":"Get current user profile","operationId":"GetMe","responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/handlers.meResponse"}}}},"patch":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Me"],"summary":"Update current user profile","operationId":"UpdateMe","parameters":[{"description":"Patch profile","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.updateMeRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/models.User"}}}}},"/me/api-keys":{"get":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"produces":["application/json"],"tags":["MeAPIKeys"],"summary":"List my API keys","operationId":"ListUserAPIKeys","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/handlers.userAPIKeyOut"}}}}},"post":{"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"description":"Returns the plaintext key once. Store it securely on the client side.","consumes":["application/json"],"produces":["application/json"],"tags":["MeAPIKeys"],"summary":"Create a new user API key","operationId":"CreateUserAPIKey","parameters":[{"description":"Key options","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.createUserKeyRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/handlers.userAPIKeyOut"}}}}},"/me/api-keys/{id}":{"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["MeAPIKeys"],"summary":"Delete a user API key","operationId":"DeleteUserAPIKey","parameters":[{"type":"string","description":"Key ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content"}}}},"/orgs":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"List organizations I belong to","operationId":"listMyOrgs","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/models.Organization"}}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"post":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Create organization","operationId":"createOrg","parameters":[{"description":"Org payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.orgCreateReq"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/models.Organization"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"409":{"description":"Conflict","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Get organization","operationId":"getOrg","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/models.Organization"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Delete organization (owner)","operationId":"deleteOrg","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"patch":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Update organization (owner/admin)","operationId":"updateOrg","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"description":"Update payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.orgUpdateReq"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/models.Organization"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/api-keys":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"List org-scoped API keys (no secrets)","operationId":"listOrgKeys","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/models.APIKey"}}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"post":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Create org key/secret pair (owner/admin)","operationId":"createOrgKey","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"description":"Key name + optional expiry","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.orgKeyCreateReq"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/handlers.orgKeyCreateResp"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/api-keys/{key_id}":{"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Delete org key (owner/admin)","operationId":"deleteOrgKey","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"type":"string","description":"Key ID (UUID)","name":"key_id","in":"path","required":true}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/members":{"get":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"List members in org","operationId":"listMembers","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/handlers.memberOut"}}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}},"post":{"security":[{"BearerAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Orgs"],"summary":"Add or update a member (owner/admin)","operationId":"addOrUpdateMember","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"description":"User \u0026 role","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/handlers.memberUpsertReq"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/handlers.memberOut"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/orgs/{id}/members/{user_id}":{"delete":{"security":[{"BearerAuth":[]}],"produces":["application/json"],"tags":["Orgs"],"summary":"Remove a member (owner/admin)","operationId":"removeMember","parameters":[{"type":"string","description":"Org ID (UUID)","name":"id","in":"path","required":true},{"type":"string","description":"User ID (UUID)","name":"user_id","in":"path","required":true}],"responses":{"204":{"description":"Removed"},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/utils.ErrorResponse"}}}}},"/servers":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns servers for the organization in X-Org-ID. Optional filters: status, role.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"List servers (org scoped)","operationId":"ListServers","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Filter by status (pending|provisioning|ready|failed)","name":"status","in":"query"},{"type":"string","description":"Filter by role","name":"role","in":"query"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.ServerResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list servers","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Creates a server bound to the org in X-Org-ID. Validates that ssh_key_id belongs to the org.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Create server (org scoped)","operationId":"CreateServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Server payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateServerRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.ServerResponse"}},"400":{"description":"invalid json / missing fields / invalid status / invalid ssh_key_id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"create failed","schema":{"type":"string"}}}}},"/servers/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns one server in the given organization.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Get server by ID (org scoped)","operationId":"GetServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Server ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.ServerResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes the server.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Delete server (org scoped)","operationId":"DeleteServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Server ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}},"patch":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Partially update fields; changing ssh_key_id validates ownership.","consumes":["application/json"],"produces":["application/json"],"tags":["Servers"],"summary":"Update server (org scoped)","operationId":"UpdateServer","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Server ID (UUID)","name":"id","in":"path","required":true},{"description":"Fields to update","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.UpdateServerRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.ServerResponse"}},"400":{"description":"invalid id / invalid json / invalid status / invalid ssh_key_id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"update failed","schema":{"type":"string"}}}}},"/ssh":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns ssh keys for the organization in X-Org-ID.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"List ssh keys (org scoped)","operationId":"ListPublicSshKeys","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.SshResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list keys","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Generates an RSA or ED25519 keypair, saves it, and returns metadata. For RSA you may set bits (2048/3072/4096). Default is 4096. ED25519 ignores bits.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"Create ssh keypair (org scoped)","operationId":"CreateSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Key generation options","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateSSHRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.SshResponse"}},"400":{"description":"invalid json / invalid bits","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"generation/create failed","schema":{"type":"string"}}}}},"/ssh/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns public key fields. Append `?reveal=true` to include the private key PEM.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"Get ssh key by ID (org scoped)","operationId":"GetSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"SSH Key ID (UUID)","name":"id","in":"path","required":true},{"type":"boolean","description":"Reveal private key PEM","name":"reveal","in":"query"}],"responses":{"200":{"description":"When reveal=true","schema":{"$ref":"#/definitions/dto.SshRevealResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes a keypair.","consumes":["application/json"],"produces":["application/json"],"tags":["Ssh"],"summary":"Delete ssh keypair (org scoped)","operationId":"DeleteSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"SSH Key ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}}},"/ssh/{id}/download":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Download `part=public|private|both` of the keypair. `both` returns a zip file.","produces":["application/json"],"tags":["Ssh"],"summary":"Download ssh key files by ID (org scoped)","operationId":"DownloadSSHKey","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header","required":true},{"type":"string","description":"SSH Key ID (UUID)","name":"id","in":"path","required":true},{"enum":["public","private","both"],"type":"string","description":"Which part to download","name":"part","in":"query","required":true}],"responses":{"200":{"description":"file content","schema":{"type":"string"}},"400":{"description":"invalid id / invalid part","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"download failed","schema":{"type":"string"}}}}},"/taints":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Returns node taints for the organization in X-Org-ID. Filters: `key`, `value`, and `q` (key contains). Add `include=node_pools` to include linked node pools.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"List node pool taints (org scoped)","operationId":"ListTaints","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Exact key","name":"key","in":"query"},{"type":"string","description":"Exact value","name":"value","in":"query"},{"type":"string","description":"key contains (case-insensitive)","name":"q","in":"query"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/dto.TaintResponse"}}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"failed to list node taints","schema":{"type":"string"}}}},"post":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Creates a taint.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Create node taint (org scoped)","operationId":"CreateTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"description":"Taint payload","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.CreateTaintRequest"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/dto.TaintResponse"}},"400":{"description":"invalid json / missing fields / invalid node_pool_ids","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"create failed","schema":{"type":"string"}}}}},"/taints/{id}":{"get":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Get node taint by ID (org scoped)","operationId":"GetTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Node Taint ID (UUID)","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TaintResponse"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"fetch failed","schema":{"type":"string"}}}},"delete":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Permanently deletes the taint.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Delete taint (org scoped)","operationId":"DeleteTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Node Taint ID (UUID)","name":"id","in":"path","required":true}],"responses":{"204":{"description":"No Content","schema":{"type":"string"}},"400":{"description":"invalid id","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"500":{"description":"delete failed","schema":{"type":"string"}}}},"patch":{"security":[{"BearerAuth":[]},{"OrgKeyAuth":[]},{"OrgSecretAuth":[]}],"description":"Partially update taint fields.","consumes":["application/json"],"produces":["application/json"],"tags":["Taints"],"summary":"Update node taint (org scoped)","operationId":"UpdateTaint","parameters":[{"type":"string","description":"Organization UUID","name":"X-Org-ID","in":"header"},{"type":"string","description":"Node Taint ID (UUID)","name":"id","in":"path","required":true},{"description":"Fields to update","name":"body","in":"body","required":true,"schema":{"$ref":"#/definitions/dto.UpdateTaintRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/dto.TaintResponse"}},"400":{"description":"invalid id / invalid json","schema":{"type":"string"}},"401":{"description":"Unauthorized","schema":{"type":"string"}},"403":{"description":"organization required","schema":{"type":"string"}},"404":{"description":"not found","schema":{"type":"string"}},"500":{"description":"update failed","schema":{"type":"string"}}}}}},"definitions":{"dto.AnnotationResponse":{"type":"object","properties":{"created_at":{"type":"string"},"id":{"type":"string"},"key":{"type":"string"},"organization_id":{"type":"string"},"updated_at":{"type":"string"},"value":{"type":"string"}}},"dto.AuthStartResponse":{"type":"object","properties":{"auth_url":{"type":"string","example":"https://accounts.google.com/o/oauth2/v2/auth?client_id=..."}}},"dto.CreateAnnotationRequest":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}},"dto.CreateLabelRequest":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}},"dto.CreateSSHRequest":{"type":"object","properties":{"bits":{"description":"Only for RSA","type":"integer"},"comment":{"type":"string","example":"deploy@autoglue"},"name":{"type":"string"},"type":{"description":"\"rsa\" (default) or \"ed25519\"","type":"string"}}},"dto.CreateServerRequest":{"type":"object","properties":{"hostname":{"type":"string"},"private_ip_address":{"type":"string"},"public_ip_address":{"type":"string"},"role":{"type":"string","example":"master|worker|bastion"},"ssh_key_id":{"type":"string"},"ssh_user":{"type":"string"},"status":{"type":"string","example":"pending|provisioning|ready|failed"}}},"dto.CreateTaintRequest":{"type":"object","properties":{"effect":{"type":"string"},"key":{"type":"string"},"value":{"type":"string"}}},"dto.EnqueueRequest":{"type":"object"},"dto.JWK":{"type":"object","properties":{"alg":{"type":"string","example":"RS256"},"e":{"type":"string","example":"AQAB"},"kid":{"type":"string","example":"7c6f1d0a-7a98-4e6a-9dbf-6b1af4b9f345"},"kty":{"type":"string","example":"RSA"},"n":{"type":"string"},"use":{"type":"string","example":"sig"},"x":{"type":"string"}}},"dto.JWKS":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/definitions/dto.JWK"}}}},"dto.Job":{"type":"object","properties":{"attempts":{"type":"integer","example":0},"created_at":{"type":"string","example":"2025-11-04T09:30:00Z"},"id":{"type":"string","example":"01HF7SZK8Z8WG1M3J7S2Z8M2N6"},"last_error":{"type":"string","example":"error message"},"max_attempts":{"type":"integer","example":3},"payload":{},"queue":{"type":"string","example":"default"},"run_at":{"type":"string","example":"2025-11-04T09:30:00Z"},"status":{"enum":["queued|running|succeeded|failed|canceled|retrying|scheduled"],"allOf":[{"$ref":"#/definitions/dto.JobStatus"}],"example":"queued"},"type":{"type":"string","example":"email.send"},"updated_at":{"type":"string","example":"2025-11-04T09:30:00Z"}}},"dto.JobStatus":{"type":"string","enum":["queued","running","succeeded","failed","canceled","retrying","scheduled"],"x-enum-varnames":["StatusQueued","StatusRunning","StatusSucceeded","StatusFailed","StatusCanceled","StatusRetrying","StatusScheduled"]},"dto.LabelResponse":{"type":"object","properties":{"created_at":{"type":"string"},"id":{"type":"string"},"key":{"type":"string"},"organization_id":{"type":"string"},"updated_at":{"type":"string"},"value":{"type":"string"}}},"dto.LogoutRequest":{"type":"object","properties":{"refresh_token":{"type":"string","example":"m0l9o8rT3t0V8d3eFf..."}}},"dto.PageJob":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/definitions/dto.Job"}},"page":{"type":"integer","example":1},"page_size":{"type":"integer","example":25},"total":{"type":"integer","example":120}}},"dto.QueueInfo":{"type":"object","properties":{"failed":{"type":"integer","example":5},"name":{"type":"string","example":"default"},"pending":{"type":"integer","example":42},"running":{"type":"integer","example":3},"scheduled":{"type":"integer","example":7}}},"dto.RefreshRequest":{"type":"object","properties":{"refresh_token":{"type":"string","example":"m0l9o8rT3t0V8d3eFf..."}}},"dto.ServerResponse":{"type":"object","properties":{"created_at":{"type":"string"},"hostname":{"type":"string"},"id":{"type":"string"},"organization_id":{"type":"string"},"private_ip_address":{"type":"string"},"public_ip_address":{"type":"string"},"role":{"type":"string"},"ssh_key_id":{"type":"string"},"ssh_user":{"type":"string"},"status":{"type":"string"},"updated_at":{"type":"string"}}},"dto.SshResponse":{"type":"object","properties":{"created_at":{"type":"string"},"fingerprint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"organization_id":{"type":"string"},"public_key":{"type":"string"},"updated_at":{"type":"string"}}},"dto.SshRevealResponse":{"type":"object","properties":{"created_at":{"type":"string"},"fingerprint":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"organization_id":{"type":"string"},"private_key":{"type":"string"},"public_key":{"type":"string"},"updated_at":{"type":"string"}}},"dto.TaintResponse":{"type":"object","properties":{"created_at":{"type":"string"},"effect":{"type":"string"},"id":{"type":"string"},"key":{"type":"string"},"organization_id":{"type":"string"},"updated_at":{"type":"string"},"value":{"type":"string"}}},"dto.TokenPair":{"type":"object","properties":{"access_token":{"type":"string","example":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ij..."},"expires_in":{"type":"integer","example":3600},"refresh_token":{"type":"string","example":"m0l9o8rT3t0V8d3eFf...."},"token_type":{"type":"string","example":"Bearer"}}},"dto.UpdateAnnotationRequest":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}},"dto.UpdateLabelRequest":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}},"dto.UpdateServerRequest":{"type":"object","properties":{"hostname":{"type":"string"},"private_ip_address":{"type":"string"},"public_ip_address":{"type":"string"},"role":{"type":"string","example":"master|worker|bastion"},"ssh_key_id":{"type":"string"},"ssh_user":{"type":"string"},"status":{"type":"string","example":"pending|provisioning|ready|failed"}}},"dto.UpdateTaintRequest":{"type":"object","properties":{"effect":{"type":"string"},"key":{"type":"string"},"value":{"type":"string"}}},"handlers.HealthStatus":{"type":"object","properties":{"status":{"type":"string","example":"ok"}}},"handlers.createUserKeyRequest":{"type":"object","properties":{"expires_in_hours":{"description":"optional TTL","type":"integer"},"name":{"type":"string"}}},"handlers.meResponse":{"type":"object","properties":{"avatar_url":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"display_name":{"type":"string"},"emails":{"type":"array","items":{"$ref":"#/definitions/models.UserEmail"}},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"is_admin":{"type":"boolean"},"is_disabled":{"type":"boolean"},"organizations":{"type":"array","items":{"$ref":"#/definitions/models.Organization"}},"primary_email":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"handlers.memberOut":{"type":"object","properties":{"email":{"type":"string"},"role":{"description":"owner/admin/member","type":"string"},"user_id":{"type":"string","format":"uuid"}}},"handlers.memberUpsertReq":{"type":"object","properties":{"role":{"type":"string","example":"member"},"user_id":{"type":"string","format":"uuid"}}},"handlers.orgCreateReq":{"type":"object","properties":{"domain":{"type":"string","example":"acme.com"},"name":{"type":"string","example":"Acme Corp"}}},"handlers.orgKeyCreateReq":{"type":"object","properties":{"expires_in_hours":{"type":"integer","example":720},"name":{"type":"string","example":"automation-bot"}}},"handlers.orgKeyCreateResp":{"type":"object","properties":{"created_at":{"type":"string"},"expires_at":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"org_key":{"description":"shown once:","type":"string"},"org_secret":{"description":"shown once:","type":"string"},"scope":{"description":"\"org\"","type":"string"}}},"handlers.orgUpdateReq":{"type":"object","properties":{"domain":{"type":"string"},"name":{"type":"string"}}},"handlers.updateMeRequest":{"type":"object","properties":{"display_name":{"type":"string"}}},"handlers.userAPIKeyOut":{"type":"object","properties":{"created_at":{"type":"string"},"expires_at":{"type":"string"},"id":{"type":"string","format":"uuid"},"last_used_at":{"type":"string"},"name":{"type":"string"},"plain":{"description":"Shown only on create:","type":"string"},"scope":{"description":"\"user\"","type":"string"}}},"models.APIKey":{"type":"object","properties":{"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"id":{"type":"string","format":"uuid"},"last_used_at":{"type":"string","format":"date-time"},"name":{"type":"string"},"org_id":{"type":"string","format":"uuid"},"prefix":{"type":"string"},"revoked":{"type":"boolean"},"scope":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"user_id":{"type":"string","format":"uuid"}}},"models.Organization":{"type":"object","properties":{"created_at":{"type":"string","format":"date-time"},"domain":{"type":"string"},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"name":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"models.User":{"type":"object","properties":{"avatar_url":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"display_name":{"type":"string"},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"is_admin":{"type":"boolean"},"is_disabled":{"type":"boolean"},"primary_email":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"models.UserEmail":{"type":"object","properties":{"created_at":{"type":"string","format":"date-time"},"email":{"type":"string"},"id":{"description":"example: 3fa85f64-5717-4562-b3fc-2c963f66afa6","type":"string","format":"uuid"},"is_primary":{"type":"boolean"},"is_verified":{"type":"boolean"},"updated_at":{"type":"string","format":"date-time"},"user":{"$ref":"#/definitions/models.User"},"user_id":{"type":"string","format":"uuid"}}},"utils.ErrorResponse":{"type":"object","properties":{"code":{"description":"A machine-readable error code, e.g. \"validation_error\"\nexample: validation_error","type":"string"},"message":{"description":"Human-readable message\nexample: slug is required","type":"string"}}}},"securityDefinitions":{"ApiKeyAuth":{"description":"User API key","type":"apiKey","name":"X-API-KEY","in":"header"},"BearerAuth":{"description":"Bearer token authentication","type":"apiKey","name":"Authorization","in":"header"},"OrgKeyAuth":{"description":"Org-level key/secret authentication","type":"apiKey","name":"X-ORG-KEY","in":"header"},"OrgSecretAuth":{"description":"Org-level secret","type":"apiKey","name":"X-ORG-SECRET","in":"header"}}} \ No newline at end of file +{ + "schemes": [ + "http", + "https" + ], + "swagger": "2.0", + "info": { + "description": "API for managing K3s clusters across cloud providers", + "title": "AutoGlue API", + "contact": { + "name": "GlueOps" + }, + "version": "1.0" + }, + "host": "localhost:8080", + "basePath": "/api/v1", + "paths": { + "/.well-known/jwks.json": { + "get": { + "description": "Returns the JSON Web Key Set for token verification", + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "summary": "Get JWKS", + "operationId": "getJWKS", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.JWKS" + } + } + } + } + }, + "/admin/archer/jobs": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Paginated background jobs with optional filters. Search `q` may match id, type, error, payload (implementation-dependent).", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ArcherAdmin" + ], + "summary": "List Archer jobs (admin)", + "operationId": "AdminListArcherJobs", + "parameters": [ + { + "enum": [ + "queued", + "running", + "succeeded", + "failed", + "canceled", + "retrying", + "scheduled" + ], + "type": "string", + "description": "Filter by status", + "name": "status", + "in": "query" + }, + { + "type": "string", + "description": "Filter by queue name / worker name", + "name": "queue", + "in": "query" + }, + { + "type": "string", + "description": "Free-text search", + "name": "q", + "in": "query" + }, + { + "type": "integer", + "default": 1, + "description": "Page number", + "name": "page", + "in": "query" + }, + { + "maximum": 100, + "minimum": 1, + "type": "integer", + "default": 25, + "description": "Items per page", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.PageJob" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "forbidden", + "schema": { + "type": "string" + } + }, + "500": { + "description": "internal error", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Create a job immediately or schedule it for the future via `run_at`.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ArcherAdmin" + ], + "summary": "Enqueue a new Archer job (admin)", + "operationId": "AdminEnqueueArcherJob", + "parameters": [ + { + "description": "Job parameters", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.EnqueueRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.Job" + } + }, + "400": { + "description": "invalid json or missing fields", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "forbidden", + "schema": { + "type": "string" + } + }, + "500": { + "description": "internal error", + "schema": { + "type": "string" + } + } + } + } + }, + "/admin/archer/jobs/{id}/cancel": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Set job status to canceled if cancellable. For running jobs, this only affects future picks; wire to Archer if you need active kill.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ArcherAdmin" + ], + "summary": "Cancel an Archer job (admin)", + "operationId": "AdminCancelArcherJob", + "parameters": [ + { + "type": "string", + "description": "Job ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.Job" + } + }, + "400": { + "description": "invalid job or not cancellable", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "forbidden", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + } + } + } + }, + "/admin/archer/jobs/{id}/retry": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Marks the job retriable (DB flip). Swap this for an Archer admin call if you expose one.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ArcherAdmin" + ], + "summary": "Retry a failed/canceled Archer job (admin)", + "operationId": "AdminRetryArcherJob", + "parameters": [ + { + "type": "string", + "description": "Job ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.Job" + } + }, + "400": { + "description": "invalid job or not eligible", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "forbidden", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + } + } + } + }, + "/admin/archer/queues": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Summary metrics per queue (pending, running, failed, scheduled).", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ArcherAdmin" + ], + "summary": "List Archer queues (admin)", + "operationId": "AdminListArcherQueues", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.QueueInfo" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "forbidden", + "schema": { + "type": "string" + } + }, + "500": { + "description": "internal error", + "schema": { + "type": "string" + } + } + } + } + }, + "/annotations": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns annotations for the organization in X-Org-ID. Filters: `key`, `value`, and `q` (key contains). Add `include=node_pools` to include linked node pools.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Annotations" + ], + "summary": "List annotations (org scoped)", + "operationId": "ListAnnotations", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Exact key", + "name": "key", + "in": "query" + }, + { + "type": "string", + "description": "Exact value", + "name": "value", + "in": "query" + }, + { + "type": "string", + "description": "key contains (case-insensitive)", + "name": "q", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.AnnotationResponse" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "failed to list annotations", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Creates an annotation.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Annotations" + ], + "summary": "Create annotation (org scoped)", + "operationId": "CreateAnnotation", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "description": "Annotation payload", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.CreateAnnotationRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.AnnotationResponse" + } + }, + "400": { + "description": "invalid json / missing fields", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "create failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/annotations/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns one annotation. Add `include=node_pools` to include node pools.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Annotations" + ], + "summary": "Get annotation by ID (org scoped)", + "operationId": "GetAnnotation", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Annotation ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.AnnotationResponse" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "fetch failed", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Permanently deletes the annotation.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Annotations" + ], + "summary": "Delete annotation (org scoped)", + "operationId": "DeleteAnnotation", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Annotation ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "delete failed", + "schema": { + "type": "string" + } + } + } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Partially update annotation fields.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Annotations" + ], + "summary": "Update annotation (org scoped)", + "operationId": "UpdateAnnotation", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Annotation ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Fields to update", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UpdateAnnotationRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.AnnotationResponse" + } + }, + "400": { + "description": "invalid id / invalid json", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "update failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/auth/logout": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "summary": "Revoke refresh token family (logout everywhere)", + "operationId": "Logout", + "parameters": [ + { + "description": "Refresh token", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.LogoutRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/auth/refresh": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "summary": "Rotate refresh token", + "operationId": "Refresh", + "parameters": [ + { + "description": "Refresh token", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.RefreshRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.TokenPair" + } + } + } + } + }, + "/auth/{provider}/callback": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "summary": "Handle social login callback", + "operationId": "AuthCallback", + "parameters": [ + { + "type": "string", + "description": "google|github", + "name": "provider", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.TokenPair" + } + } + } + } + }, + "/auth/{provider}/start": { + "post": { + "description": "Returns provider authorization URL for the frontend to redirect", + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "summary": "Begin social login", + "operationId": "AuthStart", + "parameters": [ + { + "type": "string", + "description": "google|github", + "name": "provider", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.AuthStartResponse" + } + } + } + } + }, + "/healthz": { + "get": { + "description": "Returns 200 OK when the service is up", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Health" + ], + "summary": "Basic health check", + "operationId": "HealthCheck // operationId", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.HealthStatus" + } + } + } + } + }, + "/labels": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns node labels for the organization in X-Org-ID. Filters: `key`, `value`, and `q` (key contains). Add `include=node_pools` to include linked node groups.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "List node labels (org scoped)", + "operationId": "ListLabels", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Exact key", + "name": "key", + "in": "query" + }, + { + "type": "string", + "description": "Exact value", + "name": "value", + "in": "query" + }, + { + "type": "string", + "description": "Key contains (case-insensitive)", + "name": "q", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.LabelResponse" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "failed to list node taints", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Creates a label.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "Create label (org scoped)", + "operationId": "CreateLabel", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "description": "Label payload", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.CreateLabelRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.LabelResponse" + } + }, + "400": { + "description": "invalid json / missing fields / invalid node_pool_ids", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "create failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/labels/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns one label.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "Get label by ID (org scoped)", + "operationId": "GetLabel", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Label ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.LabelResponse" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "fetch failed", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Permanently deletes the label.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "Delete label (org scoped)", + "operationId": "DeleteLabel", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Label ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "delete failed", + "schema": { + "type": "string" + } + } + } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Partially update label fields.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Labels" + ], + "summary": "Update label (org scoped)", + "operationId": "UpdateLabel", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Label ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Fields to update", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UpdateLabelRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.LabelResponse" + } + }, + "400": { + "description": "invalid id / invalid json", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "update failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/me": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "ApiKeyAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Me" + ], + "summary": "Get current user profile", + "operationId": "GetMe", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.meResponse" + } + } + } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + }, + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Me" + ], + "summary": "Update current user profile", + "operationId": "UpdateMe", + "parameters": [ + { + "description": "Patch profile", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.updateMeRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.User" + } + } + } + } + }, + "/me/api-keys": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "ApiKeyAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "MeAPIKeys" + ], + "summary": "List my API keys", + "operationId": "ListUserAPIKeys", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/handlers.userAPIKeyOut" + } + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + }, + { + "ApiKeyAuth": [] + } + ], + "description": "Returns the plaintext key once. Store it securely on the client side.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "MeAPIKeys" + ], + "summary": "Create a new user API key", + "operationId": "CreateUserAPIKey", + "parameters": [ + { + "description": "Key options", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.createUserKeyRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/handlers.userAPIKeyOut" + } + } + } + } + }, + "/me/api-keys/{id}": { + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "MeAPIKeys" + ], + "summary": "Delete a user API key", + "operationId": "DeleteUserAPIKey", + "parameters": [ + { + "type": "string", + "description": "Key ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/orgs": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "List organizations I belong to", + "operationId": "listMyOrgs", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Organization" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Create organization", + "operationId": "createOrg", + "parameters": [ + { + "description": "Org payload", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.orgCreateReq" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/models.Organization" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + }, + "409": { + "description": "Conflict", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + } + }, + "/orgs/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Get organization", + "operationId": "getOrg", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.Organization" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Delete organization (owner)", + "operationId": "deleteOrg", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "Deleted" + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Update organization (owner/admin)", + "operationId": "updateOrg", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Update payload", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.orgUpdateReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.Organization" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + } + }, + "/orgs/{id}/api-keys": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "List org-scoped API keys (no secrets)", + "operationId": "listOrgKeys", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.APIKey" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Create org key/secret pair (owner/admin)", + "operationId": "createOrgKey", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Key name + optional expiry", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.orgKeyCreateReq" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/handlers.orgKeyCreateResp" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + } + }, + "/orgs/{id}/api-keys/{key_id}": { + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Delete org key (owner/admin)", + "operationId": "deleteOrgKey", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Key ID (UUID)", + "name": "key_id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "Deleted" + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + } + }, + "/orgs/{id}/members": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "List members in org", + "operationId": "listMembers", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/handlers.memberOut" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Add or update a member (owner/admin)", + "operationId": "addOrUpdateMember", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "User \u0026 role", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.memberUpsertReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.memberOut" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + } + }, + "/orgs/{id}/members/{user_id}": { + "delete": { + "security": [ + { + "BearerAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Orgs" + ], + "summary": "Remove a member (owner/admin)", + "operationId": "removeMember", + "parameters": [ + { + "type": "string", + "description": "Org ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "User ID (UUID)", + "name": "user_id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "Removed" + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/utils.ErrorResponse" + } + } + } + } + }, + "/servers": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns servers for the organization in X-Org-ID. Optional filters: status, role.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Servers" + ], + "summary": "List servers (org scoped)", + "operationId": "ListServers", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Filter by status (pending|provisioning|ready|failed)", + "name": "status", + "in": "query" + }, + { + "type": "string", + "description": "Filter by role", + "name": "role", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.ServerResponse" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "failed to list servers", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Creates a server bound to the org in X-Org-ID. Validates that ssh_key_id belongs to the org.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Servers" + ], + "summary": "Create server (org scoped)", + "operationId": "CreateServer", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "description": "Server payload", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.CreateServerRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.ServerResponse" + } + }, + "400": { + "description": "invalid json / missing fields / invalid status / invalid ssh_key_id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "create failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/servers/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns one server in the given organization.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Servers" + ], + "summary": "Get server by ID (org scoped)", + "operationId": "GetServer", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Server ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.ServerResponse" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "fetch failed", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Permanently deletes the server.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Servers" + ], + "summary": "Delete server (org scoped)", + "operationId": "DeleteServer", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Server ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "delete failed", + "schema": { + "type": "string" + } + } + } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Partially update fields; changing ssh_key_id validates ownership.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Servers" + ], + "summary": "Update server (org scoped)", + "operationId": "UpdateServer", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Server ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Fields to update", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UpdateServerRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.ServerResponse" + } + }, + "400": { + "description": "invalid id / invalid json / invalid status / invalid ssh_key_id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "update failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/ssh": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns ssh keys for the organization in X-Org-ID.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Ssh" + ], + "summary": "List ssh keys (org scoped)", + "operationId": "ListPublicSshKeys", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.SshResponse" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "failed to list keys", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Generates an RSA or ED25519 keypair, saves it, and returns metadata. For RSA you may set bits (2048/3072/4096). Default is 4096. ED25519 ignores bits.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Ssh" + ], + "summary": "Create ssh keypair (org scoped)", + "operationId": "CreateSSHKey", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "description": "Key generation options", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.CreateSSHRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.SshResponse" + } + }, + "400": { + "description": "invalid json / invalid bits", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "generation/create failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/ssh/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns public key fields. Append `?reveal=true` to include the private key PEM.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Ssh" + ], + "summary": "Get ssh key by ID (org scoped)", + "operationId": "GetSSHKey", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "SSH Key ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Reveal private key PEM", + "name": "reveal", + "in": "query" + } + ], + "responses": { + "200": { + "description": "When reveal=true", + "schema": { + "$ref": "#/definitions/dto.SshRevealResponse" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "fetch failed", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Permanently deletes a keypair.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Ssh" + ], + "summary": "Delete ssh keypair (org scoped)", + "operationId": "DeleteSSHKey", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "SSH Key ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "delete failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/ssh/{id}/download": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Download `part=public|private|both` of the keypair. `both` returns a zip file.", + "produces": [ + "application/json" + ], + "tags": [ + "Ssh" + ], + "summary": "Download ssh key files by ID (org scoped)", + "operationId": "DownloadSSHKey", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "SSH Key ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "enum": [ + "public", + "private", + "both" + ], + "type": "string", + "description": "Which part to download", + "name": "part", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "file content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "invalid id / invalid part", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "download failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/taints": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Returns node taints for the organization in X-Org-ID. Filters: `key`, `value`, and `q` (key contains). Add `include=node_pools` to include linked node pools.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Taints" + ], + "summary": "List node pool taints (org scoped)", + "operationId": "ListTaints", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Exact key", + "name": "key", + "in": "query" + }, + { + "type": "string", + "description": "Exact value", + "name": "value", + "in": "query" + }, + { + "type": "string", + "description": "key contains (case-insensitive)", + "name": "q", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.TaintResponse" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "failed to list node taints", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Creates a taint.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Taints" + ], + "summary": "Create node taint (org scoped)", + "operationId": "CreateTaint", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "description": "Taint payload", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.CreateTaintRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.TaintResponse" + } + }, + "400": { + "description": "invalid json / missing fields / invalid node_pool_ids", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "create failed", + "schema": { + "type": "string" + } + } + } + } + }, + "/taints/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Taints" + ], + "summary": "Get node taint by ID (org scoped)", + "operationId": "GetTaint", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Node Taint ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.TaintResponse" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "fetch failed", + "schema": { + "type": "string" + } + } + } + }, + "delete": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Permanently deletes the taint.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Taints" + ], + "summary": "Delete taint (org scoped)", + "operationId": "DeleteTaint", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Node Taint ID (UUID)", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content", + "schema": { + "type": "string" + } + }, + "400": { + "description": "invalid id", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "500": { + "description": "delete failed", + "schema": { + "type": "string" + } + } + } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + }, + { + "OrgKeyAuth": [] + }, + { + "OrgSecretAuth": [] + } + ], + "description": "Partially update taint fields.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Taints" + ], + "summary": "Update node taint (org scoped)", + "operationId": "UpdateTaint", + "parameters": [ + { + "type": "string", + "description": "Organization UUID", + "name": "X-Org-ID", + "in": "header" + }, + { + "type": "string", + "description": "Node Taint ID (UUID)", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Fields to update", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UpdateTaintRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.TaintResponse" + } + }, + "400": { + "description": "invalid id / invalid json", + "schema": { + "type": "string" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "403": { + "description": "organization required", + "schema": { + "type": "string" + } + }, + "404": { + "description": "not found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "update failed", + "schema": { + "type": "string" + } + } + } + } + } + }, + "definitions": { + "dto.AnnotationResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "key": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.AuthStartResponse": { + "type": "object", + "properties": { + "auth_url": { + "type": "string", + "example": "https://accounts.google.com/o/oauth2/v2/auth?client_id=..." + } + } + }, + "dto.CreateAnnotationRequest": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.CreateLabelRequest": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.CreateSSHRequest": { + "type": "object", + "properties": { + "bits": { + "description": "Only for RSA", + "type": "integer" + }, + "comment": { + "type": "string", + "example": "deploy@autoglue" + }, + "name": { + "type": "string" + }, + "type": { + "description": "\"rsa\" (default) or \"ed25519\"", + "type": "string" + } + } + }, + "dto.CreateServerRequest": { + "type": "object", + "properties": { + "hostname": { + "type": "string" + }, + "private_ip_address": { + "type": "string" + }, + "public_ip_address": { + "type": "string" + }, + "role": { + "type": "string", + "example": "master|worker|bastion" + }, + "ssh_key_id": { + "type": "string" + }, + "ssh_user": { + "type": "string" + }, + "status": { + "type": "string", + "example": "pending|provisioning|ready|failed" + } + } + }, + "dto.CreateTaintRequest": { + "type": "object", + "properties": { + "effect": { + "type": "string" + }, + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.EnqueueRequest": { + "type": "object" + }, + "dto.JWK": { + "type": "object", + "properties": { + "alg": { + "type": "string", + "example": "RS256" + }, + "e": { + "type": "string", + "example": "AQAB" + }, + "kid": { + "type": "string", + "example": "7c6f1d0a-7a98-4e6a-9dbf-6b1af4b9f345" + }, + "kty": { + "type": "string", + "example": "RSA" + }, + "n": { + "type": "string" + }, + "use": { + "type": "string", + "example": "sig" + }, + "x": { + "type": "string" + } + } + }, + "dto.JWKS": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.JWK" + } + } + } + }, + "dto.Job": { + "type": "object", + "properties": { + "attempts": { + "type": "integer", + "example": 0 + }, + "created_at": { + "type": "string", + "example": "2025-11-04T09:30:00Z" + }, + "id": { + "type": "string", + "example": "01HF7SZK8Z8WG1M3J7S2Z8M2N6" + }, + "last_error": { + "type": "string", + "example": "error message" + }, + "max_attempts": { + "type": "integer", + "example": 3 + }, + "payload": {}, + "queue": { + "type": "string", + "example": "default" + }, + "run_at": { + "type": "string", + "example": "2025-11-04T09:30:00Z" + }, + "status": { + "enum": [ + "queued|running|succeeded|failed|canceled|retrying|scheduled" + ], + "allOf": [ + { + "$ref": "#/definitions/dto.JobStatus" + } + ], + "example": "queued" + }, + "type": { + "type": "string", + "example": "email.send" + }, + "updated_at": { + "type": "string", + "example": "2025-11-04T09:30:00Z" + } + } + }, + "dto.JobStatus": { + "type": "string", + "enum": [ + "queued", + "running", + "succeeded", + "failed", + "canceled", + "retrying", + "scheduled" + ], + "x-enum-varnames": [ + "StatusQueued", + "StatusRunning", + "StatusSucceeded", + "StatusFailed", + "StatusCanceled", + "StatusRetrying", + "StatusScheduled" + ] + }, + "dto.LabelResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "key": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.LogoutRequest": { + "type": "object", + "properties": { + "refresh_token": { + "type": "string", + "example": "m0l9o8rT3t0V8d3eFf..." + } + } + }, + "dto.PageJob": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.Job" + } + }, + "page": { + "type": "integer", + "example": 1 + }, + "page_size": { + "type": "integer", + "example": 25 + }, + "total": { + "type": "integer", + "example": 120 + } + } + }, + "dto.QueueInfo": { + "type": "object", + "properties": { + "failed": { + "type": "integer", + "example": 5 + }, + "name": { + "type": "string", + "example": "default" + }, + "pending": { + "type": "integer", + "example": 42 + }, + "running": { + "type": "integer", + "example": 3 + }, + "scheduled": { + "type": "integer", + "example": 7 + } + } + }, + "dto.RefreshRequest": { + "type": "object", + "properties": { + "refresh_token": { + "type": "string", + "example": "m0l9o8rT3t0V8d3eFf..." + } + } + }, + "dto.ServerResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "hostname": { + "type": "string" + }, + "id": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "private_ip_address": { + "type": "string" + }, + "public_ip_address": { + "type": "string" + }, + "role": { + "type": "string" + }, + "ssh_key_id": { + "type": "string" + }, + "ssh_user": { + "type": "string" + }, + "status": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "dto.SshResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "fingerprint": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "public_key": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "dto.SshRevealResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "fingerprint": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "private_key": { + "type": "string" + }, + "public_key": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "dto.TaintResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "effect": { + "type": "string" + }, + "id": { + "type": "string" + }, + "key": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.TokenPair": { + "type": "object", + "properties": { + "access_token": { + "type": "string", + "example": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ij..." + }, + "expires_in": { + "type": "integer", + "example": 3600 + }, + "refresh_token": { + "type": "string", + "example": "m0l9o8rT3t0V8d3eFf...." + }, + "token_type": { + "type": "string", + "example": "Bearer" + } + } + }, + "dto.UpdateAnnotationRequest": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.UpdateLabelRequest": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "dto.UpdateServerRequest": { + "type": "object", + "properties": { + "hostname": { + "type": "string" + }, + "private_ip_address": { + "type": "string" + }, + "public_ip_address": { + "type": "string" + }, + "role": { + "type": "string", + "example": "master|worker|bastion" + }, + "ssh_key_id": { + "type": "string" + }, + "ssh_user": { + "type": "string" + }, + "status": { + "type": "string", + "example": "pending|provisioning|ready|failed" + } + } + }, + "dto.UpdateTaintRequest": { + "type": "object", + "properties": { + "effect": { + "type": "string" + }, + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "handlers.HealthStatus": { + "type": "object", + "properties": { + "status": { + "type": "string", + "example": "ok" + } + } + }, + "handlers.createUserKeyRequest": { + "type": "object", + "properties": { + "expires_in_hours": { + "description": "optional TTL", + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, + "handlers.meResponse": { + "type": "object", + "properties": { + "avatar_url": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "display_name": { + "type": "string" + }, + "emails": { + "type": "array", + "items": { + "$ref": "#/definitions/models.UserEmail" + } + }, + "id": { + "description": "example: 3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type": "string", + "format": "uuid" + }, + "is_admin": { + "type": "boolean" + }, + "is_disabled": { + "type": "boolean" + }, + "organizations": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Organization" + } + }, + "primary_email": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "handlers.memberOut": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "role": { + "description": "owner/admin/member", + "type": "string" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "handlers.memberUpsertReq": { + "type": "object", + "properties": { + "role": { + "type": "string", + "example": "member" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "handlers.orgCreateReq": { + "type": "object", + "properties": { + "domain": { + "type": "string", + "example": "acme.com" + }, + "name": { + "type": "string", + "example": "Acme Corp" + } + } + }, + "handlers.orgKeyCreateReq": { + "type": "object", + "properties": { + "expires_in_hours": { + "type": "integer", + "example": 720 + }, + "name": { + "type": "string", + "example": "automation-bot" + } + } + }, + "handlers.orgKeyCreateResp": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "expires_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "org_key": { + "description": "shown once:", + "type": "string" + }, + "org_secret": { + "description": "shown once:", + "type": "string" + }, + "scope": { + "description": "\"org\"", + "type": "string" + } + } + }, + "handlers.orgUpdateReq": { + "type": "object", + "properties": { + "domain": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "handlers.updateMeRequest": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + } + } + }, + "handlers.userAPIKeyOut": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "expires_at": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_used_at": { + "type": "string" + }, + "name": { + "type": "string" + }, + "plain": { + "description": "Shown only on create:", + "type": "string" + }, + "scope": { + "description": "\"user\"", + "type": "string" + } + } + }, + "models.APIKey": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "expires_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_used_at": { + "type": "string", + "format": "date-time" + }, + "name": { + "type": "string" + }, + "org_id": { + "type": "string", + "format": "uuid" + }, + "prefix": { + "type": "string" + }, + "revoked": { + "type": "boolean" + }, + "scope": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "models.Organization": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "domain": { + "type": "string" + }, + "id": { + "description": "example: 3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "models.User": { + "type": "object", + "properties": { + "avatar_url": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "display_name": { + "type": "string" + }, + "id": { + "description": "example: 3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type": "string", + "format": "uuid" + }, + "is_admin": { + "type": "boolean" + }, + "is_disabled": { + "type": "boolean" + }, + "primary_email": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "models.UserEmail": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "email": { + "type": "string" + }, + "id": { + "description": "example: 3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type": "string", + "format": "uuid" + }, + "is_primary": { + "type": "boolean" + }, + "is_verified": { + "type": "boolean" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user": { + "$ref": "#/definitions/models.User" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "utils.ErrorResponse": { + "type": "object", + "properties": { + "code": { + "description": "A machine-readable error code, e.g. \"validation_error\"\nexample: validation_error", + "type": "string" + }, + "message": { + "description": "Human-readable message\nexample: slug is required", + "type": "string" + } + } + } + }, + "securityDefinitions": { + "ApiKeyAuth": { + "description": "User API key", + "type": "apiKey", + "name": "X-API-KEY", + "in": "header" + }, + "BearerAuth": { + "description": "Bearer token authentication", + "type": "apiKey", + "name": "Authorization", + "in": "header" + }, + "OrgKeyAuth": { + "description": "Org-level key/secret authentication", + "type": "apiKey", + "name": "X-ORG-KEY", + "in": "header" + }, + "OrgSecretAuth": { + "description": "Org-level secret", + "type": "apiKey", + "name": "X-ORG-SECRET", + "in": "header" + } + } +} \ No newline at end of file