hzel
ReferenceStructures

Program Structures

ProgramRecord, ProgramDetail, ProgramInvitation, and PendingInvitationView.

ProgramRecord

Returned by POST /api/v1/programs, GET /api/v1/programs, and PATCH /api/v1/programs/{id}/permissions.

FieldTypeDescription
idstring (UUID)Unique program identifier.
namestringHuman-readable program name.
descriptionstringDescription of the program's purpose.
created_bystring (UUID)User ID of the admin who created the program.
created_atstring (ISO 8601)UTC timestamp when the program was created.
can_create_containersbooleanWhether accepted members of this program may provision containers.
{
  "id": "11111111-0000-0000-0000-000000000001",
  "name": "Research Cohort",
  "description": "Participants in the summer 2025 research program.",
  "created_by": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "created_at": "2025-06-01T08:00:00Z",
  "can_create_containers": true
}

ProgramDetail

Returned by GET /api/v1/programs/{id}. Contains all ProgramRecord fields (flattened via #[serde(flatten)]) plus a members array of accepted participants.

FieldTypeDescription
(all ProgramRecord fields)See above.
membersarray of ProgramMemberUsers who have accepted an invitation to this program.

Each ProgramMember:

FieldTypeDescription
user_idstring (UUID)Unique user identifier.
emailstringEmail address of the member.
display_namestring | nullDisplay name from the user's OIDC profile, if available.
invited_atstring (ISO 8601)UTC timestamp when the invitation was originally sent.
responded_atstring (ISO 8601) | nullUTC timestamp when the user accepted. null if not yet responded (only accepted members appear in this list).
{
  "id": "11111111-0000-0000-0000-000000000001",
  "name": "Research Cohort",
  "description": "Participants in the summer 2025 research program.",
  "created_by": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "created_at": "2025-06-01T08:00:00Z",
  "can_create_containers": true,
  "members": [
    {
      "user_id": "aaaaaaaa-0000-0000-0000-000000000001",
      "email": "bob@example.com",
      "display_name": "Bob Example",
      "invited_at": "2025-06-02T09:00:00Z",
      "responded_at": "2025-06-02T10:30:00Z"
    }
  ]
}

ProgramInvitation

Returned by POST /api/v1/programs/{id}/invite.

FieldTypeDescription
idstring (UUID)Unique invitation identifier.
program_idstring (UUID)ID of the program the user is being invited to.
user_idstring (UUID)ID of the invited user.
invited_bystring (UUID)User ID of the admin who sent the invitation.
invited_atstring (ISO 8601)UTC timestamp when the invitation was created.
responded_atstring (ISO 8601) | nullUTC timestamp when the user responded. null if pending.
responsestring | null"accepted" or "declined" once the user responds. null while pending.
{
  "id": "bbbbbbbb-0000-0000-0000-000000000001",
  "program_id": "11111111-0000-0000-0000-000000000001",
  "user_id": "aaaaaaaa-0000-0000-0000-000000000001",
  "invited_by": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "invited_at": "2025-06-02T09:00:00Z",
  "responded_at": null,
  "response": null
}

PendingInvitationView

Returned by GET /api/v1/programs/invitations/pending. A denormalized read model that includes program and inviter details so the user can make an informed accept/decline decision in a single request.

FieldTypeDescription
idstring (UUID)Invitation identifier. Pass this to POST /api/v1/programs/invitations/{id}/respond.
program_idstring (UUID)ID of the program the invitation is for.
program_namestringName of the program.
program_descriptionstringDescription of the program.
invited_by_display_namestring | nullDisplay name of the admin who sent the invitation. null if the admin has no display name.
invited_by_emailstringEmail address of the admin who sent the invitation.
invited_atstring (ISO 8601)UTC timestamp when the invitation was sent.
{
  "id": "bbbbbbbb-0000-0000-0000-000000000001",
  "program_id": "11111111-0000-0000-0000-000000000001",
  "program_name": "Research Cohort",
  "program_description": "Participants in the summer 2025 research program.",
  "invited_by_display_name": "Alice Admin",
  "invited_by_email": "alice@example.com",
  "invited_at": "2025-06-02T09:00:00Z"
}