{
  "openapi": "3.0.3",
  "info": {
    "title": "IwiConnect API",
    "version": "1.31.1",
    "description": "The IwiConnect API lets your consenting system, asset management platform or internal tooling create\nprojects, send them to iwi, and follow the kōrero that comes back.\n\n## Authentication\n\nEvery request carries an API key in the `Authorization` header as a bearer token. Keys are created by an account\nowner under **API keys** in the portal, and they are prefixed so you can tell at a glance what you are holding:\n`iwk_live_` for production and `iwk_test_` for sandbox accounts.\n\n```\nAuthorization: Bearer iwk_live_7Qx4...\n```\n\nA key inherits the single account it was created under and can do nothing that account cannot already do. Query string\nauthentication is not supported.\n\n## Scopes\n\n| Scope | Grants |\n| --- | --- |\n| `projects:read` | List and fetch projects, engagements, documents and activity logs. |\n| `projects:write` | Create and update projects, assign them, add and edit notes, close, complete and reopen. |\n| `projects:send` | Send a project to iwi and request a report. Consumes tokens. |\n| `iwi:read` | Look up iwi, search by name, and resolve coordinates to rohe. |\n| `team:read` | Read team members, pending invitations, receipts and reports. |\n| `team:write` | Rename the team, change member roles, revoke member access. |\n| `users:invite` | Invite users, resend and expire invitations, including bulk invites. |\n| `groups:read` | List assignment groups. |\n| `groups:write` | Create, update and delete assignment groups. |\n| `files:write` | Request an upload URL and finalise an upload. |\n| `files:read` | Generate download links for documents you already have access to. |\n| `billing:read` | Read token balance, invoices and receipts. |\n\nScopes do not nest. Granting `projects:write` does not grant `projects:read`. A request missing a scope returns 403\nbefore anything runs, so nothing was created, updated or charged.\n\n## The response envelope\n\nEvery response, success or failure, carries the same four fields. List endpoints put their pagination inside\n`response_object`, so the array you want is at `response_object.data`.\n\n## Names and text\n\nField names are snake_case and spelled the New Zealand way, so `organisation_id` and `colour`. Requests also accept\nthe American spellings. Names come back with macrons intact, so send and store UTF-8.\n\n## Rate limits\n\nRequests are limited per key over a rolling fifteen minute window. Standard `RateLimit-*` headers come back on every\nresponse. Exceeding the limit returns 429.\n\n## Versioning\n\nThere is no version in the path. Additive changes ship without notice, so parse defensively and ignore fields you do\nnot recognise. Anything that would break a working integration gets advance notice by email to the key owner.",
    "contact": {
      "name": "IwiConnect support",
      "email": "support@iwiconnect.com",
      "url": "https://docs.iwiconnect.com"
    }
  },
  "servers": [
    {
      "url": "https://api.iwiconnect.com",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Projects",
      "description": "Create projects, send them to iwi, and track them through to completion."
    },
    {
      "name": "Engagements",
      "description": "The thread on a project: responses and internal notes."
    },
    {
      "name": "Iwi",
      "description": "Look up iwi and resolve coordinates to rohe."
    },
    {
      "name": "Teams",
      "description": "Your account, its people and its records."
    },
    {
      "name": "Users",
      "description": "Identity and invitations."
    },
    {
      "name": "Organisations",
      "description": "The entities your projects are about."
    },
    {
      "name": "Groups",
      "description": "Named sets of people you can assign work to."
    },
    {
      "name": "Files",
      "description": "Presigned uploads and short lived download links."
    },
    {
      "name": "Billing",
      "description": "Token purchases and GST invoices."
    }
  ],
  "externalDocs": {
    "description": "IwiConnect API documentation",
    "url": "https://docs.iwiconnect.com"
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "An IwiConnect API key, created under API keys in the portal."
      }
    },
    "schemas": {
      "User": {
        "type": "object",
        "nullable": true,
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "profile_picture_url": {
            "type": "string",
            "nullable": true
          },
          "teams": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserTeam"
            }
          },
          "iwi": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserIwi"
            }
          }
        },
        "required": [
          "id"
        ]
      },
      "UserTeam": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "current_credit_balance": {
            "type": "number"
          },
          "role": {
            "$ref": "#/components/schemas/UserRole"
          },
          "account": {
            "type": "object",
            "nullable": true,
            "properties": {
              "region": {
                "type": "string",
                "nullable": true
              },
              "local_authority": {
                "type": "string",
                "nullable": true
              },
              "organisation_type": {
                "type": "string",
                "nullable": true
              },
              "national": {
                "type": "boolean",
                "nullable": true
              },
              "sandbox": {
                "type": "boolean",
                "nullable": true
              }
            }
          }
        },
        "required": [
          "id",
          "name",
          "current_credit_balance",
          "role"
        ]
      },
      "UserRole": {
        "type": "string",
        "enum": [
          "OWNER",
          "MEMBER"
        ]
      },
      "UserIwi": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "role": {
            "$ref": "#/components/schemas/UserRole"
          }
        },
        "required": [
          "id",
          "name",
          "slug",
          "role"
        ]
      },
      "InviteUserBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "role": {
            "$ref": "#/components/schemas/UserRole"
          },
          "org_department": {
            "type": "string"
          },
          "org_department_other": {
            "type": "string"
          },
          "org_role": {
            "type": "string"
          },
          "org_role_other": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "email",
          "role"
        ]
      },
      "BulkInviteResponse": {
        "type": "object",
        "nullable": true,
        "properties": {
          "invited_count": {
            "type": "number"
          },
          "skipped_count": {
            "type": "number"
          },
          "failed_count": {
            "type": "number"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkInviteResult"
            }
          }
        },
        "required": [
          "invited_count",
          "skipped_count",
          "failed_count",
          "results"
        ]
      },
      "BulkInviteResult": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/BulkInviteStatus"
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "invitation_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          }
        },
        "required": [
          "name",
          "email",
          "status",
          "message",
          "invitation_id"
        ]
      },
      "BulkInviteStatus": {
        "type": "string",
        "enum": [
          "INVITED",
          "SKIPPED",
          "FAILED"
        ]
      },
      "BulkInviteBody": {
        "type": "object",
        "properties": {
          "invitations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InviteUserBody"
            },
            "minItems": 1,
            "maxItems": 200
          }
        },
        "required": [
          "invitations"
        ]
      },
      "Invitation": {
        "type": "object",
        "nullable": true,
        "properties": {
          "team": {
            "$ref": "#/components/schemas/NamedAccount"
          },
          "iwi": {
            "$ref": "#/components/schemas/NamedAccount"
          },
          "role": {
            "$ref": "#/components/schemas/UserRole"
          }
        },
        "required": [
          "role"
        ]
      },
      "NamedAccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name"
        ]
      },
      "ProjectSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "reference": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "$ref": "#/components/schemas/ProjectType"
          },
          "phase": {
            "$ref": "#/components/schemas/ProjectPhase"
          },
          "status": {
            "$ref": "#/components/schemas/ProjectStatus"
          },
          "priority": {
            "$ref": "#/components/schemas/ProjectPriority"
          },
          "address": {
            "type": "string"
          },
          "latitude": {
            "type": "number"
          },
          "longitude": {
            "type": "number"
          },
          "organisation_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "organisation": {
            "$ref": "#/components/schemas/OrganisationSummary"
          },
          "recipient_team": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NamedAccount"
              },
              {
                "nullable": true
              }
            ]
          },
          "creator_iwi": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NamedAccount"
              },
              {
                "nullable": true
              }
            ]
          },
          "iwi_name": {
            "type": "string",
            "nullable": true
          },
          "is_iwi_created": {
            "type": "boolean"
          },
          "assigned_to": {
            "$ref": "#/components/schemas/Person"
          },
          "assigned_to_group": {
            "$ref": "#/components/schemas/AssignmentGroup"
          },
          "sender_assigned_to": {
            "$ref": "#/components/schemas/Person"
          },
          "sender_assigned_to_group": {
            "$ref": "#/components/schemas/AssignmentGroup"
          },
          "start_date": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          },
          "end_date": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          },
          "respond_by_date": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          },
          "created_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          },
          "updated_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          },
          "closed_on": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "type",
          "address",
          "latitude",
          "longitude",
          "start_date",
          "end_date",
          "respond_by_date",
          "created_on",
          "updated_on",
          "closed_on"
        ]
      },
      "ProjectType": {
        "type": "string",
        "enum": [
          "EMERGENCY_WORKS",
          "ENVIRONMENTAL_SPILL_HEALTH_INCIDENT",
          "ACCIDENTAL_DISCOVERY",
          "LAND_USE_CONSENT",
          "SUBDIVISION_CONSENT",
          "DISCHARGE_CONSENT_APPLICATION",
          "WATER_TAKE_CONSENT",
          "COASTAL_STREAM_CONSENT",
          "POLICY_OR_POLICY_CHANGE",
          "PLAN_CHANGE",
          "DESIGNATIONS_NOTICES_OF_REQUIREMENT",
          "INFRASTRUCTURE_DEVELOPMENT",
          "ARCHAEOLOGICAL_AUTHORITY",
          "RENEWABLE_ENERGY",
          "SITE_WORKS_START",
          "CULTURAL_MONITORING",
          "BUILDING_OPENING",
          "TREE_CONSENT",
          "CONSERVATION",
          "SCHEDULED_MAINTENANCE",
          "EARTHWORKS",
          "OTHER"
        ]
      },
      "ProjectPhase": {
        "type": "string",
        "nullable": true,
        "enum": [
          "PRE_START",
          "WORKS_UNDERWAY",
          "COMPLETE",
          "PRE_LODGEMENT",
          "LODGED",
          "FURTHER_INFORMATION_REQUESTED",
          "ACCEPTANCE_DECISION",
          "NOTIFICATION",
          "SUBMISSIONS",
          "FURTHER_SUBMISSIONS",
          "HEARING",
          "DECISION",
          "APPEAL",
          "OPERATIVE",
          "ON_HOLD",
          "WITHDRAWN",
          null
        ]
      },
      "ProjectStatus": {
        "type": "string",
        "nullable": true,
        "enum": [
          "DRAFT",
          "NEW",
          "IN_PROGRESS",
          "AWAITING_RESPONSE",
          "UPDATED",
          "COMPLETE",
          "CLOSED",
          null
        ]
      },
      "ProjectPriority": {
        "type": "string",
        "nullable": true,
        "enum": [
          "HIGH",
          "MEDIUM",
          "LOW",
          null
        ]
      },
      "OrganisationSummary": {
        "type": "object",
        "nullable": true,
        "properties": {
          "name": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          },
          "postcode": {
            "type": "string",
            "nullable": true
          },
          "latitude": {
            "type": "number"
          },
          "longitude": {
            "type": "number"
          }
        },
        "required": [
          "name",
          "address",
          "latitude",
          "longitude"
        ]
      },
      "Person": {
        "type": "object",
        "nullable": true,
        "properties": {
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "profile_picture_url": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "first_name",
          "last_name",
          "profile_picture_url"
        ]
      },
      "AssignmentGroup": {
        "type": "object",
        "nullable": true,
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "colour": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "colour"
        ]
      },
      "CreateProjectBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "type": {
            "$ref": "#/components/schemas/ProjectType"
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "example": "2026-11-03"
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "example": "2027-04-30"
          },
          "respond_by_date": {
            "type": "string",
            "format": "date",
            "example": "2026-10-14"
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FileReference"
            }
          },
          "draft": {
            "type": "boolean"
          },
          "phase": {
            "$ref": "#/components/schemas/ProjectPhase"
          },
          "reference": {
            "type": "string"
          },
          "address": {
            "type": "string",
            "nullable": true
          },
          "latitude": {
            "type": "number",
            "nullable": true
          },
          "longitude": {
            "type": "number",
            "nullable": true
          },
          "iwi": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Iwi slugs. Ignored when the location resolves to a single iwi."
          },
          "organisation_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "organisation": {
            "$ref": "#/components/schemas/OrganisationSummary"
          },
          "contact": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "role": {
                "type": "string"
              },
              "phone": {
                "type": "string"
              },
              "email": {
                "type": "string"
              }
            },
            "required": [
              "name",
              "role",
              "phone"
            ]
          },
          "quantity": {
            "type": "number",
            "description": "Buy tokens as part of the submission. One of 1, 5, 10, 20, 50."
          },
          "recipient_team_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "name",
          "description",
          "type",
          "start_date",
          "end_date",
          "respond_by_date",
          "files",
          "draft"
        ]
      },
      "FileReference": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ]
      },
      "Project": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ProjectSummary"
          },
          {
            "type": "object",
            "nullable": true,
            "properties": {
              "can_edit": {
                "type": "boolean"
              },
              "can_respond": {
                "type": "boolean"
              },
              "can_assign": {
                "type": "boolean"
              },
              "can_assign_sender": {
                "type": "boolean"
              },
              "can_send": {
                "type": "boolean"
              },
              "can_close": {
                "type": "boolean"
              },
              "can_reopen": {
                "type": "boolean"
              },
              "can_download_receipt": {
                "type": "boolean"
              },
              "can_add_notes": {
                "type": "boolean"
              }
            },
            "required": [
              "can_edit",
              "can_respond",
              "can_assign",
              "can_assign_sender",
              "can_send",
              "can_close",
              "can_reopen",
              "can_download_receipt",
              "can_add_notes"
            ]
          }
        ]
      },
      "UpdateProjectBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "reference": {
            "type": "string"
          },
          "type": {
            "$ref": "#/components/schemas/ProjectType"
          },
          "phase": {
            "$ref": "#/components/schemas/ProjectPhase"
          },
          "start_date": {
            "type": "string",
            "format": "date"
          },
          "end_date": {
            "type": "string",
            "format": "date"
          },
          "respond_by_date": {
            "type": "string",
            "format": "date"
          }
        },
        "required": [
          "start_date",
          "end_date",
          "respond_by_date"
        ]
      },
      "SendProjectBody": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "minLength": 1
          },
          "iwi": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "message"
        ]
      },
      "AssignProjectBody": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "group_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "side": {
            "type": "string",
            "enum": [
              "recipient",
              "sender"
            ]
          }
        },
        "required": [
          "user_id"
        ]
      },
      "RespondToProjectBody": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FileReference"
            }
          }
        },
        "required": [
          "message",
          "files"
        ]
      },
      "CompleteProjectBody": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          }
        }
      },
      "CloseProjectBody": {
        "type": "object",
        "properties": {
          "all": {
            "type": "boolean"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "all"
        ]
      },
      "RequestReportBody": {
        "type": "object",
        "properties": {
          "all": {
            "type": "boolean"
          }
        }
      },
      "Engagement": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "project_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "content": {
            "type": "string",
            "nullable": true
          },
          "is_internal": {
            "type": "boolean"
          },
          "meeting_type": {
            "$ref": "#/components/schemas/MeetingType"
          },
          "created_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          },
          "updated_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          },
          "created_by": {
            "$ref": "#/components/schemas/Person"
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Document"
            }
          }
        },
        "required": [
          "id",
          "is_internal",
          "created_on",
          "updated_on"
        ]
      },
      "MeetingType": {
        "type": "string",
        "nullable": true,
        "enum": [
          "PHONE_CALL",
          "VIDEO_CALL",
          "IN_PERSON",
          "EMAIL",
          "OTHER",
          null
        ]
      },
      "Document": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "mime_type": {
            "type": "string",
            "nullable": true
          },
          "size": {
            "type": "number",
            "nullable": true
          },
          "project_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "engagement_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "created_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          },
          "updated_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          }
        },
        "required": [
          "id",
          "created_on",
          "updated_on"
        ]
      },
      "Log": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "action": {
            "$ref": "#/components/schemas/LogAction"
          },
          "resource": {
            "$ref": "#/components/schemas/LogResource"
          },
          "property": {
            "type": "string",
            "nullable": true
          },
          "from": {
            "type": "string",
            "nullable": true
          },
          "to": {
            "type": "string",
            "nullable": true
          },
          "project_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "created_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          },
          "created_by": {
            "$ref": "#/components/schemas/Person"
          }
        },
        "required": [
          "id",
          "action",
          "resource",
          "created_on"
        ]
      },
      "LogAction": {
        "type": "string",
        "enum": [
          "CREATED",
          "UPDATED",
          "DELETED",
          "RESPONDED",
          "SENT",
          "REOPENED",
          "CLOSED",
          "COMPLETED"
        ]
      },
      "LogResource": {
        "type": "string",
        "enum": [
          "PROJECT",
          "TEAM"
        ]
      },
      "NoteBody": {
        "type": "object",
        "properties": {
          "content": {
            "type": "string",
            "minLength": 1
          },
          "meeting_type": {
            "$ref": "#/components/schemas/MeetingType"
          }
        },
        "required": [
          "content",
          "meeting_type"
        ]
      },
      "IwiCountResponse": {
        "type": "object",
        "nullable": true,
        "properties": {
          "iwi": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "slug": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              },
              "required": [
                "slug",
                "name"
              ]
            }
          },
          "can_select_iwi": {
            "type": "boolean"
          }
        },
        "required": [
          "iwi",
          "can_select_iwi"
        ]
      },
      "IwiCountBody": {
        "type": "object",
        "properties": {
          "lat": {
            "type": "number",
            "example": -40.8752
          },
          "lon": {
            "type": "number",
            "example": 175.0662
          }
        },
        "required": [
          "lat",
          "lon"
        ]
      },
      "Iwi": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "example": "Te Āti Awa ki Whakarongotai"
          },
          "slug": {
            "type": "string",
            "example": "te-ati-awa-ki-whakarongotai"
          },
          "logo_url": {
            "type": "string",
            "nullable": true
          },
          "primary_colour": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "name",
          "slug"
        ]
      },
      "Team": {
        "type": "object",
        "nullable": true,
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "users": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TeamMember"
            }
          },
          "invitations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TeamInvitation"
            }
          }
        },
        "required": [
          "id",
          "name",
          "users",
          "invitations"
        ]
      },
      "TeamMember": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "role": {
            "$ref": "#/components/schemas/UserRole"
          },
          "org_department": {
            "type": "string",
            "nullable": true
          },
          "org_department_other": {
            "type": "string",
            "nullable": true
          },
          "org_role": {
            "type": "string",
            "nullable": true
          },
          "org_role_other": {
            "type": "string",
            "nullable": true
          },
          "created_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          }
        },
        "required": [
          "id",
          "first_name",
          "last_name",
          "email",
          "role",
          "created_on"
        ]
      },
      "TeamInvitation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/InvitationStatus"
          },
          "role": {
            "$ref": "#/components/schemas/UserRole"
          },
          "org_department": {
            "type": "string",
            "nullable": true
          },
          "org_department_other": {
            "type": "string",
            "nullable": true
          },
          "org_role": {
            "type": "string",
            "nullable": true
          },
          "org_role_other": {
            "type": "string",
            "nullable": true
          },
          "created_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          },
          "expired_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          }
        },
        "required": [
          "id",
          "name",
          "email",
          "status",
          "role",
          "created_on",
          "expired_on"
        ]
      },
      "InvitationStatus": {
        "type": "string",
        "enum": [
          "PENDING",
          "EXPIRED",
          "ACCEPTED"
        ]
      },
      "UpdateTeamNameBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          }
        },
        "required": [
          "name"
        ]
      },
      "UpdateTeamMemberBody": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "role": {
            "$ref": "#/components/schemas/UserRole"
          },
          "org_department": {
            "type": "string"
          },
          "org_department_other": {
            "type": "string"
          },
          "org_role": {
            "type": "string"
          },
          "org_role_other": {
            "type": "string"
          }
        },
        "required": [
          "user_id",
          "role"
        ]
      },
      "RevokeTeamMemberBody": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "user_id"
        ]
      },
      "Receipt": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "document_id": {
            "type": "string",
            "format": "uuid"
          },
          "project_name": {
            "type": "string"
          },
          "receipt_number": {
            "type": "string"
          },
          "submission_number": {
            "type": "string"
          },
          "created_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          }
        },
        "required": [
          "id",
          "document_id",
          "project_name",
          "receipt_number",
          "submission_number",
          "created_on"
        ]
      },
      "Report": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "document_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "project_name": {
            "type": "string"
          },
          "reference": {
            "type": "string"
          },
          "created_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          }
        },
        "required": [
          "id",
          "document_id",
          "project_name",
          "reference",
          "created_on"
        ]
      },
      "Invoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "number": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string"
          },
          "quantity": {
            "type": "number"
          },
          "amount_total": {
            "type": "number",
            "nullable": true,
            "description": "Total in cents, GST inclusive."
          },
          "currency": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "download_url": {
            "type": "string",
            "nullable": true
          },
          "hosted_url": {
            "type": "string",
            "nullable": true
          },
          "created_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          }
        },
        "required": [
          "id",
          "number",
          "description",
          "quantity",
          "amount_total",
          "currency",
          "status",
          "download_url",
          "hosted_url",
          "created_on"
        ]
      },
      "Organisation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "postcode": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "mobile": {
            "type": "string"
          },
          "created_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          },
          "updated_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Contact"
            }
          }
        },
        "required": [
          "id",
          "created_on",
          "updated_on"
        ]
      },
      "Contact": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "role": {
            "type": "string",
            "nullable": true
          },
          "role_type": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "created_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          }
        },
        "required": [
          "id",
          "created_on"
        ]
      },
      "UpdateOrganisationBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "postcode": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "mobile": {
            "type": "string"
          }
        }
      },
      "RecipientGroup": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "colour": {
            "type": "string",
            "example": "#5b644a"
          },
          "member_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "created_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          },
          "updated_on": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-20T03:14:00.000Z"
          }
        },
        "required": [
          "id",
          "name",
          "colour",
          "member_ids",
          "created_on",
          "updated_on"
        ]
      },
      "GroupBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "colour": {
            "type": "string",
            "example": "#5b644a"
          },
          "memberIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "description": {
            "type": "string",
            "nullable": true,
            "maxLength": 500
          }
        },
        "required": [
          "name",
          "colour",
          "memberIds"
        ]
      },
      "PresignUploadResponse": {
        "type": "object",
        "nullable": true,
        "properties": {
          "documentId": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string"
          },
          "fields": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        },
        "required": [
          "documentId",
          "url",
          "fields"
        ]
      },
      "PresignUploadBody": {
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string",
            "minLength": 1
          },
          "mimeType": {
            "type": "string"
          },
          "size": {
            "type": "integer",
            "minimum": 0,
            "exclusiveMinimum": true,
            "maximum": 104857600
          },
          "category": {
            "$ref": "#/components/schemas/UploadCategory"
          }
        },
        "required": [
          "fileName",
          "mimeType",
          "size"
        ]
      },
      "UploadCategory": {
        "type": "string",
        "enum": [
          "document",
          "image",
          "gisLayer"
        ]
      },
      "CompleteUploadResponse": {
        "type": "object",
        "nullable": true,
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "size": {
            "type": "number"
          },
          "mimeType": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "size"
        ]
      },
      "CompleteUploadBody": {
        "type": "object",
        "properties": {
          "documentId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "documentId"
        ]
      },
      "Download": {
        "type": "object",
        "nullable": true,
        "properties": {
          "url": {
            "type": "string",
            "description": "Short lived signed URL. Fetch it when you need it rather than storing it."
          }
        },
        "required": [
          "url"
        ]
      }
    },
    "parameters": {}
  },
  "paths": {
    "/user": {
      "get": {
        "operationId": "getCurrentUser",
        "summary": "Who the key belongs to",
        "description": "The identity behind the key: name, teams, role on each team, token balance, and any iwi accounts. Needs no scopes.\n\nNeeds no scopes.",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "$ref": "#/components/schemas/User"
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/user/invite": {
      "post": {
        "operationId": "inviteUser",
        "summary": "Invite one person",
        "description": "Emails an invitation to join the account the key belongs to.\n\nRequires the `users:invite` scope.",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteUserBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/user/invite/bulk": {
      "post": {
        "operationId": "bulkInviteUsers",
        "summary": "Invite in bulk",
        "description": "Up to 200 invitations in one request. Each row is processed independently, and re-running is safe because existing members and pending invitations are skipped.\n\nRequires the `users:invite` scope.",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkInviteBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "$ref": "#/components/schemas/BulkInviteResponse"
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/user/invitation/{id}": {
      "get": {
        "operationId": "getInvitation",
        "summary": "Read an invitation",
        "description": "One invitation with its status and expiry.\n\nRequires the `team:read` scope.",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "$ref": "#/components/schemas/Invitation"
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/user/invitation/{id}/resend": {
      "post": {
        "operationId": "resendInvitation",
        "summary": "Resend an invitation",
        "description": "Sends the email again and extends the expiry.\n\nRequires the `users:invite` scope.",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/user/invitation/{id}/expire": {
      "post": {
        "operationId": "expireInvitation",
        "summary": "Expire an invitation",
        "description": "Cancels a pending invitation immediately.\n\nRequires the `users:invite` scope.",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/user/invitation/{id}/accept": {
      "post": {
        "operationId": "acceptInvitation",
        "summary": "Accept an invitation",
        "description": "Runs as the person being invited, during sign up. An integration almost never calls it.\n\nNeeds no scopes.",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects": {
      "get": {
        "operationId": "listProjects",
        "summary": "List projects",
        "description": "Every project the account can see, paged and filterable.\n\nRequires the `projects:read` scope.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 20
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "search",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "type",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "priority",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "organisation",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "local_authority",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "assigned_to",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "active",
                "closed",
                "completed"
              ]
            },
            "required": false,
            "name": "active_status",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ProjectSummary"
                          }
                        },
                        "total": {
                          "type": "number"
                        },
                        "page": {
                          "type": "number"
                        },
                        "limit": {
                          "type": "number"
                        },
                        "total_pages": {
                          "type": "number"
                        },
                        "tab_counts": {
                          "type": "object",
                          "properties": {
                            "all": {
                              "type": "number"
                            },
                            "active": {
                              "type": "number"
                            },
                            "closed": {
                              "type": "number"
                            },
                            "completed": {
                              "type": "number"
                            }
                          },
                          "required": [
                            "all",
                            "active"
                          ]
                        }
                      },
                      "required": [
                        "data",
                        "total",
                        "page",
                        "limit",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      },
      "post": {
        "operationId": "createProject",
        "summary": "Create a project",
        "description": "Creates a draft when draft is true, or creates and immediately submits when it is false. Submitting consumes a token.\n\nRequires the `projects:write` scope.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProjectBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects/{id}": {
      "get": {
        "operationId": "getProject",
        "summary": "Fetch one project",
        "description": "The full record, including the can_* flags describing what this key may do next.\n\nRequires the `projects:read` scope.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "$ref": "#/components/schemas/Project"
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      },
      "put": {
        "operationId": "updateProject",
        "summary": "Update a project",
        "description": "Editable fields are name, description, reference, type, phase and the three dates. All three dates must be present, even when only one changes.\n\nRequires the `projects:write` scope.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateProjectBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects/{id}/send": {
      "put": {
        "operationId": "sendProject",
        "summary": "Send a project",
        "description": "Submits a draft. Consumes one token and notifies the receiving iwi.\n\nRequires the `projects:send` scope.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendProjectBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects/{id}/assign": {
      "put": {
        "operationId": "assignProject",
        "summary": "Assign a project",
        "description": "Assign the project to a person or an assignment group, on your own side of the engagement.\n\nRequires the `projects:write` scope.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssignProjectBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects/{id}/respond": {
      "put": {
        "operationId": "respondToProject",
        "summary": "Respond to a project",
        "description": "Adds a visible message to the thread and notifies the other side.\n\nRequires the `projects:write` scope.",
        "tags": [
          "Engagements"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RespondToProjectBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects/{id}/complete": {
      "put": {
        "operationId": "completeProject",
        "summary": "Complete a project",
        "description": "Marks the engagement COMPLETE. Iwi accounts only.\n\nRequires the `projects:write` scope.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteProjectBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects/{id}/close": {
      "put": {
        "operationId": "closeProject",
        "summary": "Close a project",
        "description": "Closes the project off and queues the engagement report.\n\nRequires the `projects:write` scope.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloseProjectBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects/{id}/reopen": {
      "put": {
        "operationId": "reopenProject",
        "summary": "Reopen a project",
        "description": "Puts a closed project back to NEW and clears its closed date. Nothing is charged.\n\nRequires the `projects:write` scope.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects/{id}/report": {
      "post": {
        "operationId": "requestProjectReport",
        "summary": "Request a report",
        "description": "Generates a PDF engagement report covering the project and its exchanges.\n\nRequires the `projects:send` scope.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequestReportBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects/{id}/engagements": {
      "get": {
        "operationId": "listProjectEngagements",
        "summary": "Read the thread",
        "description": "Paged, newest first, with documents and author on each entry.\n\nRequires the `projects:read` scope.",
        "tags": [
          "Engagements"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Engagement"
                          }
                        },
                        "total": {
                          "type": "number"
                        },
                        "page": {
                          "type": "number"
                        },
                        "limit": {
                          "type": "number"
                        },
                        "total_pages": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "data",
                        "total",
                        "page",
                        "limit",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects/{id}/documents": {
      "get": {
        "operationId": "listProjectDocuments",
        "summary": "List project documents",
        "description": "Every document attached to the project or to an engagement on it, paged.\n\nRequires the `projects:read` scope.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Document"
                          }
                        },
                        "total": {
                          "type": "number"
                        },
                        "page": {
                          "type": "number"
                        },
                        "limit": {
                          "type": "number"
                        },
                        "total_pages": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "data",
                        "total",
                        "page",
                        "limit",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects/{id}/logs": {
      "get": {
        "operationId": "listProjectLogs",
        "summary": "Read the audit trail",
        "description": "Who changed what, when, and from which value to which.\n\nRequires the `projects:read` scope.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Log"
                          }
                        },
                        "total": {
                          "type": "number"
                        },
                        "page": {
                          "type": "number"
                        },
                        "limit": {
                          "type": "number"
                        },
                        "total_pages": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "data",
                        "total",
                        "page",
                        "limit",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects/{id}/notes": {
      "post": {
        "operationId": "createProjectNote",
        "summary": "Log a note",
        "description": "Records an interaction that happened outside the platform. Internal to your own account.\n\nRequires the `projects:write` scope.",
        "tags": [
          "Engagements"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NoteBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/projects/{id}/notes/{engagementId}": {
      "put": {
        "operationId": "updateProjectNote",
        "summary": "Edit a note",
        "description": "Replaces content and meeting_type. Only the author can edit a note.\n\nRequires the `projects:write` scope.",
        "tags": [
          "Engagements"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Engagement identifier."
            },
            "required": true,
            "description": "Engagement identifier.",
            "name": "engagementId",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NoteBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      },
      "delete": {
        "operationId": "deleteProjectNote",
        "summary": "Delete a note",
        "description": "Removes the note. The deletion itself stays in the log.\n\nRequires the `projects:write` scope.",
        "tags": [
          "Engagements"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Engagement identifier."
            },
            "required": true,
            "description": "Engagement identifier.",
            "name": "engagementId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/iwi/count": {
      "post": {
        "operationId": "countIwiForPoint",
        "summary": "Who holds mana whenua here",
        "description": "Takes a point and returns the iwi whose rohe cover it, along with whether you get to choose.\n\nRequires the `iwi:read` scope.",
        "tags": [
          "Iwi"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IwiCountBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "$ref": "#/components/schemas/IwiCountResponse"
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/iwi": {
      "get": {
        "operationId": "listIwi",
        "summary": "List iwi",
        "description": "Every iwi on the platform, with id, name and slug.\n\nRequires the `iwi:read` scope.",
        "tags": [
          "Iwi"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Iwi"
                      }
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/iwi/{id}": {
      "get": {
        "operationId": "getIwi",
        "summary": "Fetch one iwi",
        "description": "One iwi, including branding where they have set it.\n\nRequires the `iwi:read` scope.",
        "tags": [
          "Iwi"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Iwi"
                        },
                        {
                          "nullable": true
                        }
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/team/{id}": {
      "get": {
        "operationId": "getTeam",
        "summary": "Read the team",
        "description": "Members and pending invitations in one call.\n\nRequires the `team:read` scope.",
        "tags": [
          "Teams"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "$ref": "#/components/schemas/Team"
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/team/{id}/name": {
      "put": {
        "operationId": "updateTeamName",
        "summary": "Rename the team",
        "description": "The new name appears on projects you have already sent.\n\nRequires the `team:write` scope.",
        "tags": [
          "Teams"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTeamNameBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/team/{id}/role": {
      "put": {
        "operationId": "updateTeamMember",
        "summary": "Change a role",
        "description": "Promotes or demotes a member, and updates their department and role details.\n\nRequires the `team:write` scope.",
        "tags": [
          "Teams"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTeamMemberBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/team/{id}/revoke": {
      "delete": {
        "operationId": "revokeTeamMember",
        "summary": "Revoke access",
        "description": "Removes a member. Their projects, responses and notes stay where they are.\n\nRequires the `team:write` scope.",
        "tags": [
          "Teams"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevokeTeamMemberBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/team/{id}/receipts": {
      "get": {
        "operationId": "listTeamReceipts",
        "summary": "Submission receipts",
        "description": "One per project sent, each with a document_id you can turn into a download link.\n\nRequires the `team:read` scope.",
        "tags": [
          "Teams"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Receipt"
                          }
                        },
                        "total": {
                          "type": "number"
                        },
                        "page": {
                          "type": "number"
                        },
                        "limit": {
                          "type": "number"
                        },
                        "total_pages": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "data",
                        "total",
                        "page",
                        "limit",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/team/{id}/reports": {
      "get": {
        "operationId": "listTeamReports",
        "summary": "Engagement reports",
        "description": "Reports generated through POST /projects/{id}/report. They build asynchronously.\n\nRequires the `team:read` scope.",
        "tags": [
          "Teams"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Report"
                          }
                        },
                        "total": {
                          "type": "number"
                        },
                        "page": {
                          "type": "number"
                        },
                        "limit": {
                          "type": "number"
                        },
                        "total_pages": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "data",
                        "total",
                        "page",
                        "limit",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/team/{id}/invoices": {
      "get": {
        "operationId": "listTeamInvoices",
        "summary": "GST invoices",
        "description": "Invoices for token purchases, newest first.\n\nRequires the `billing:read` scope.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "default": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "exclusiveMinimum": true,
              "maximum": 100,
              "default": 10
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Invoice"
                          }
                        },
                        "total": {
                          "type": "number"
                        },
                        "page": {
                          "type": "number"
                        },
                        "limit": {
                          "type": "number"
                        },
                        "total_pages": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "data",
                        "total",
                        "page",
                        "limit",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/organisations": {
      "get": {
        "operationId": "listOrganisations",
        "summary": "List organisations",
        "description": "The entities your projects are about: developers, contractors, applicants.\n\nRequires the `projects:read` scope.",
        "tags": [
          "Organisations"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/Organisation"
                      }
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/organisations/{id}": {
      "get": {
        "operationId": "getOrganisation",
        "summary": "Fetch one organisation",
        "description": "One organisation and its contacts.\n\nRequires the `projects:read` scope.",
        "tags": [
          "Organisations"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Organisation"
                        },
                        {
                          "nullable": true
                        }
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      },
      "put": {
        "operationId": "updateOrganisation",
        "summary": "Update an organisation",
        "description": "Changes the organisation record. Existing projects keep the details they were sent with.\n\nRequires the `projects:write` scope.",
        "tags": [
          "Organisations"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateOrganisationBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Organisation"
                        },
                        {
                          "nullable": true
                        }
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      },
      "delete": {
        "operationId": "deleteOrganisation",
        "summary": "Delete an organisation",
        "description": "Deleting one leaves existing projects intact.\n\nRequires the `projects:write` scope.",
        "tags": [
          "Organisations"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/groups/{type}/{id}": {
      "get": {
        "operationId": "listGroups",
        "summary": "List assignment groups",
        "description": "Groups belonging to the owner named in the path.\n\nRequires the `groups:read` scope.",
        "tags": [
          "Groups"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "team",
                "iwi"
              ],
              "description": "Owner type: team or iwi."
            },
            "required": true,
            "description": "Owner type: team or iwi.",
            "name": "type",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "$ref": "#/components/schemas/RecipientGroup"
                      }
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      },
      "post": {
        "operationId": "createGroup",
        "summary": "Create a group",
        "description": "Creates the group and sets its members in one call.\n\nRequires the `groups:write` scope.",
        "tags": [
          "Groups"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "team",
                "iwi"
              ],
              "description": "Owner type: team or iwi."
            },
            "required": true,
            "description": "Owner type: team or iwi.",
            "name": "type",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GroupBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/RecipientGroup"
                        },
                        {
                          "nullable": true
                        }
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/groups/{type}/{id}/{groupId}": {
      "put": {
        "operationId": "updateGroup",
        "summary": "Update a group",
        "description": "Replaces the group's name, colour, description and membership.\n\nRequires the `groups:write` scope.",
        "tags": [
          "Groups"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "team",
                "iwi"
              ],
              "description": "Owner type: team or iwi."
            },
            "required": true,
            "description": "Owner type: team or iwi.",
            "name": "type",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Assignment group identifier."
            },
            "required": true,
            "description": "Assignment group identifier.",
            "name": "groupId",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GroupBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/RecipientGroup"
                        },
                        {
                          "nullable": true
                        }
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      },
      "delete": {
        "operationId": "deleteGroup",
        "summary": "Delete a group",
        "description": "Removes the group. Projects assigned to it become unassigned.\n\nRequires the `groups:write` scope.",
        "tags": [
          "Groups"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "team",
                "iwi"
              ],
              "description": "Owner type: team or iwi."
            },
            "required": true,
            "description": "Owner type: team or iwi.",
            "name": "type",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "description": "Assignment group identifier."
            },
            "required": true,
            "description": "Assignment group identifier.",
            "name": "groupId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "type": "boolean",
                      "nullable": true
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/upload/presign": {
      "post": {
        "operationId": "presignUpload",
        "summary": "Request an upload URL",
        "description": "Returns a presigned POST target that expires in a few minutes.\n\nRequires the `files:write` scope.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PresignUploadBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "$ref": "#/components/schemas/PresignUploadResponse"
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/upload/complete": {
      "post": {
        "operationId": "completeUpload",
        "summary": "Confirm an upload",
        "description": "Verifies the object landed and makes the document attachable.\n\nRequires the `files:write` scope.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteUploadBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "$ref": "#/components/schemas/CompleteUploadResponse"
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    },
    "/download/{id}": {
      "get": {
        "operationId": "downloadDocument",
        "summary": "Download a document",
        "description": "Returns a short lived signed URL for a document you can already see.\n\nRequires the `files:read` scope.",
        "tags": [
          "Files"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Resource identifier."
            },
            "required": true,
            "description": "Resource identifier.",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "status_code": {
                      "type": "number"
                    },
                    "response_object": {
                      "$ref": "#/components/schemas/Download"
                    }
                  },
                  "required": [
                    "success",
                    "message",
                    "status_code",
                    "response_object"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The body or query failed validation."
          },
          "401": {
            "description": "Missing, malformed or revoked key."
          },
          "403": {
            "description": "The key lacks a scope, or is not party to the resource."
          },
          "404": {
            "description": "Not found, or not visible to this key."
          },
          "429": {
            "description": "Rate limited. Back off and honour RateLimit-Reset."
          }
        }
      }
    }
  }
}
