{
    "platform": {
        "name": "sugu",
        "summary": "A metadata-driven application platform. One YAML document defines an application: its tables, fields and relations. Every environment generates a user interface and a REST API from that document.",
        "the_key_idea": "The YAML document is the product. To change what an application is you rewrite the document and a new version is created; there is no endpoint that adds a table or a field.",
        "docs_language": "en",
        "human_pages": {
            "marketing": "https://www.sugu.es/",
            "pricing": "https://www.sugu.es/#pricing"
        }
    },
    "authentication": {
        "scheme": "bearer",
        "header": "Authorization: Bearer sugu_<environment>_<secret>",
        "how_to_obtain": "A human creates the key in the console, under the application it belongs to. Keys cannot create keys, so an agent cannot mint its own credential or widen its own role.",
        "unauthenticated_response": "UNAUTHORIZED"
    },
    "start_here": "https://www.sugu.es/api/v1/_me",
    "endpoints": [
        {
            "url": "https://www.sugu.es/api/v1/_me",
            "auth": "key",
            "returns": "Which application and environment this key belongs to, what its role may do, and a link to every document it may read. Call this first: the token embeds an environment id, not a slug, so no other URL can be constructed without it."
        },
        {
            "url": "https://www.sugu.es/api/v1/_docs/metadata.md",
            "auth": "key",
            "returns": "The YAML contract every application is written in: the options at each level, the field types, and a complete annotated example. Read this before proposing metadata. Also available as metadata.json."
        },
        {
            "url": "https://www.sugu.es/api/v1/{slug}/{env}/_docs/agents.md",
            "auth": "key",
            "returns": "A brief for the runtime API of one environment, filtered to what this key may call, in prose rather than schema. Explains the loops that OpenAPI cannot."
        },
        {
            "url": "https://www.sugu.es/api/v1/{slug}/{env}/_docs/openapi.json",
            "auth": "key",
            "returns": "OpenAPI 3.1 for the runtime API: the generated tables of one environment, as CRUD endpoints. Describes only what this key may call."
        },
        {
            "url": "https://www.sugu.es/api/v1/{slug}/{env}/_meta/schema",
            "auth": "key",
            "returns": "The generated schema of one environment \u2014 tables, fields, types and relations \u2014 as data rather than as an API description."
        },
        {
            "url": "https://www.sugu.es/api/v1/{slug}/_admin/_docs/agents.md",
            "auth": "key",
            "returns": "A brief for the backoffice API: reading and rewriting the metadata, versions, environments, backups and hooks. Filtered to this key, and it names what the key may not do as well as what it may."
        },
        {
            "url": "https://www.sugu.es/api/v1/{slug}/_admin/_docs/openapi.json",
            "auth": "key",
            "returns": "OpenAPI 3.1 for the backoffice API. Each operation carries x-capability, and x-environments where the capability is scoped to particular environments."
        }
    ],
    "error_codes": [
        {
            "code": "UNAUTHORIZED",
            "status": 401,
            "meaning": "The bearer token is missing, malformed or expired. Stop and ask a human for a new key; retrying will not help."
        },
        {
            "code": "FORBIDDEN",
            "status": 403,
            "meaning": "This key may not perform this operation at all. Stop and report it rather than retrying."
        },
        {
            "code": "FORBIDDEN_CAPABILITY",
            "status": 403,
            "meaning": "The key's role lacks a capability. The `capability` and `action` fields name it, and `environment` names where it was needed. Report exactly that to a human instead of retrying."
        },
        {
            "code": "NOT_FOUND",
            "status": 404,
            "meaning": "The resource does not exist, or this key cannot see it. Re-read the parent collection before assuming it was deleted."
        },
        {
            "code": "VALIDATION_FAILED",
            "status": 422,
            "meaning": "The payload does not satisfy the schema. Read `error.fields`, correct the named fields and send again."
        },
        {
            "code": "FIELD_FORBIDDEN",
            "status": 422,
            "meaning": "One or more fields in the payload may not be written by this role. Remove them and resend; the remaining fields are still accepted."
        },
        {
            "code": "INTEGRITY_VIOLATION",
            "status": 409,
            "meaning": "The operation breaks a required relation \u2014 usually a delete with dependants, or a reference to a record that does not exist. Resolve the relation first."
        },
        {
            "code": "DEGRADED",
            "status": 402,
            "meaning": "The environment is degraded, normally for billing reasons. Nothing an agent can do; report it."
        },
        {
            "code": "QUOTA_EXCEEDED",
            "status": 402,
            "meaning": "The account that owns this application has used up an allowance. `allowance` names which one, with `limit` and `used` beside it. There is nothing an agent can do: the owner has to wait for the period to renew, buy a budget reset, or upgrade the plan. Report it instead of retrying."
        },
        {
            "code": "MAINTENANCE",
            "status": 503,
            "meaning": "A queued operation is rewriting this environment. Writes are refused until it finishes. Poll the environment until its status leaves `onderhoud`, then retry."
        },
        {
            "code": "ENVIRONMENT_BUSY",
            "status": 409,
            "meaning": "Another operation already holds this environment. Wait for it rather than starting a second one."
        },
        {
            "code": "METADATA_INVALID",
            "status": 422,
            "meaning": "The YAML is not a valid metadata document. `issues` carries a line, a code, a path and a message per problem; branch on `code`. Fix them and validate again before writing."
        },
        {
            "code": "STALE_BASE_VERSION",
            "status": 409,
            "meaning": "Someone else wrote a new version since the one named in `base_version`. Re-read the metadata, reapply the change on top of it and send again \u2014 do not force."
        },
        {
            "code": "OPERATION_FAILED",
            "status": 500,
            "meaning": "A queued operation failed. The reason is in the audit log, not in this response."
        },
        {
            "code": "CONFLICT",
            "status": 409,
            "meaning": "The request contradicts the current state of the resource. Re-read it before deciding what to do."
        }
    ],
    "conventions": {
        "envelope": "Every response is {\"data\": \u2026} or {\"error\": {\"code\", \"message\", \u2026}}. The code is the contract; the message follows the reader's locale and must never be branched on.",
        "rate_limit": "Sixty requests per minute per key, shared across both API surfaces. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining \u2014 pace yourself by those headers rather than by counting.",
        "versioning": "The API is versioned in the path. Everything below is v1."
    }
}