The Instances API provides administrators with full lifecycle control over tenant instances — isolated ECS services paired with dedicated MySQL schemas, each identified by a unique slug. All endpoints in this group are restricted to the primary instance (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/yohangr3/agentelanggrafh/llms.txt
Use this file to discover all available pages before exploring further.
expected_tenant="*") and require membership in the Cognito admin group. Calling these endpoints from a tenant instance returns 404.
Primary instance only. Tenant stacks do not hold the
TenantPanelAccess
IAM policy. Even if a tenant user somehow obtained admin Cognito group
membership, the IAM guard on the primary instance is the authoritative
enforcement layer — the application guard here is an additional safeguard.What is a tenant instance?
Each customer of the ERP Financial Agent platform runs in a fully isolated tenant instance: a dedicated Amazon ECS service (erp-agent-service-<tenant_id>) inside its own ECS cluster (erp-agent-cluster-<tenant_id>), backed by a dedicated RDS MySQL database (erp-rds-<tenant_id>). Infrastructure is provisioned via a CloudFormation stack named erp-agent-services-<tenant_id>.
Every provisioned instance is registered in a shared DynamoDB tenant registry table (erp-agent-tenants), which is the authoritative source of identity for all admin panel operations. Live ECS task counts and RDS status are fetched on-demand and overlaid on registry data — if AWS describe calls fail, the instance is still listed with live_status: "unknown" so no instance is silently hidden.
Authentication
All/api/admin/instances endpoints require:
- A valid Cognito JWT in the
Authorization: Bearer <token>header. - Membership in the Cognito admin group.
- Requests must be routed through the primary instance — tenant instance deployments return
404for all routes under this prefix.
Rate limits
| Endpoint | Limit |
|---|---|
GET /api/admin/instances | 30 req / minute |
POST /api/admin/instances | 5 req / minute |
POST /api/admin/instances/{tenant_id}/start | 10 req / minute |
POST /api/admin/instances/{tenant_id}/stop | 10 req / minute |
GET /api/admin/instances
List all provisioned tenant instances registered in the DynamoDBerp-agent-tenants table, each enriched with live ECS task state and RDS instance status from AWS.
Response
Ordered list of tenant instance records.
Total number of instances returned. Equals
instances.length.Example
POST /api/admin/instances
Provision a new tenant instance by dispatching theprovision-tenant.yml
GitHub Actions workflow. Returns 202 Accepted immediately — provisioning
runs asynchronously and takes approximately 15 minutes.
The workflow is idempotent — it is safe to re-run if something failed
mid-way. Each tenant_id runs in its own concurrency group
(provision-tenant-<tenant_id>), so parallel dispatches for the same slug
are serialised, never run concurrently.
GitHub token prerequisite
The endpoint reads the GitHub fine-grained PAT from the AWS Secrets Manager secret named by theGITHUB_TOKEN_SECRET_NAME environment variable. The PAT
must have Actions: write permission on the repository that hosts the
workflow.
If the secret is absent or inaccessible, the endpoint returns 503 with an
actionable error message that includes the expected secret name.
Request body
Unique slug for the new tenant. Must match
^[a-z0-9][a-z0-9-]{1,30}$
(lowercase letters, digits, and hyphens; 2–31 characters total). The slugs
production and staging are reserved and will be rejected with 400.Email address for the initial
org_admin Cognito user. When provided, the
provisioning script creates the user and stores the temporary password in
Secrets Manager under erp-agent/tenant-admin-temp-<tenant_id> (expires
after 7 days without login). Leave empty to skip admin user creation.RDS DB instance class. Accepted values:
db.t3.medium, db.t3.small,
db.t4g.medium. This controls the cost of the tenant (~37/month off for the default class).Response
Returns 202 Accepted on success.The slug of the tenant being provisioned — mirrors the request body value.
Always
"provision_dispatched" for this endpoint.Human-readable status message. Indicates the expected provisioning duration
and where to follow progress.
Direct URL to the GitHub Actions workflow runs page for
provision-tenant.yml. Use this to monitor live provisioning progress.Error responses
| Status | Condition |
|---|---|
400 | tenant_id fails the slug validation regex or is a reserved word (production, staging). |
409 | A tenant with this tenant_id already exists in the DynamoDB registry. |
503 | The GitHub PAT secret (GITHUB_TOKEN_SECRET_NAME) is missing or inaccessible in Secrets Manager. |
502 | GitHub API returned an unexpected status code (not 204). |
Example
POST /api/admin/instances//start
Turn a registered tenant instance on by setting ECSdesiredCount to 1
and starting the RDS DB instance. Updates the registry status to "on".
The instance takes approximately 3–5 minutes to become fully available after
this call returns.
Path parameters
Slug of the tenant to start. Must pass the same
^[a-z0-9][a-z0-9-]{1,30}$
validation as the create endpoint.Response
Slug of the tenant that was acted on.
Always
"start" for this endpoint.Human-readable confirmation message.
Empty string for start/stop actions (only populated by the provision endpoint).
Example
POST /api/admin/instances//stop
Turn a registered tenant instance off by setting ECSdesiredCount to
0 and stopping the RDS DB instance. Updates the registry status to
"off". The tenant URL will respond with 503 until the instance is
started again.
Path parameters
Slug of the tenant to stop.
Response
Slug of the tenant that was acted on.
Always
"stop" for this endpoint.Human-readable confirmation message.
Empty string for start/stop actions.
Example
Provisioning lifecycle
The diagram below shows the complete lifecycle of a tenant instance from initial dispatch through normal operation:DynamoDB tenant registry
Theerp-agent-tenants table is scanned by GET /api/admin/instances and
keyed on tenant_id (string). The table holds the same fields surfaced by
TenantInstanceSummary: stack_name, rds_identifier, alb_dns,
admin_email, status, created_at, and updated_at. Live ECS/RDS state
fields (live_status, running_count, desired_count, rds_status) are
not stored — they are fetched from AWS on every list call and overlaid
in-memory.
If the
erp-agent-tenants table does not yet exist (e.g. before the first
tenant is provisioned), GET /api/admin/instances returns an empty list
rather than an error.