basePath: /
definitions:
  api.AddProcessesToBundleRequest:
    properties:
      processes:
        description: Process IDs to add — each is either the 24-hex ProcessID or the
          64-hex on-chain election id.
        items:
          type: string
        type: array
    type: object
  api.InfoResponse:
    properties:
      chainId:
        type: string
      goVersion:
        type: string
      version:
        type: string
    type: object
  apicommon.APIKeyInfo:
    properties:
      createdAt:
        type: string
      createdBy:
        type: string
      expiresAt:
        type: string
      id:
        type: string
      label:
        type: string
      lastUsedAt:
        type: string
      prefix:
        type: string
      revoked:
        type: boolean
      scopes:
        items:
          type: string
        type: array
    type: object
  apicommon.AcceptOrganizationInvitation:
    properties:
      code:
        description: Invitation code
        type: string
      user:
        allOf:
        - $ref: '#/definitions/apicommon.UserInfo'
        description: User information for registration or identification
    type: object
  apicommon.AddCensusParticipantsRequest:
    properties:
      memberIds:
        description: List of existing organization member IDs to add to the census
        items:
          type: string
        type: array
    type: object
  apicommon.AddMembersJobResponse:
    properties:
      added:
        description: Number of members added
        type: integer
      errors:
        description: Errors encountered during job
        items:
          type: string
        type: array
      progress:
        description: Progress equals Added / Total * 100
        type: integer
      total:
        description: Total members in this job
        type: integer
    type: object
  apicommon.AddMembersRequest:
    properties:
      members:
        description: List of members to add
        items:
          $ref: '#/definitions/apicommon.OrgMember'
        type: array
    type: object
  apicommon.AddMembersResponse:
    properties:
      added:
        description: Number of members added
        type: integer
      errors:
        description: Errors encountered during job
        items:
          type: string
        type: array
      jobId:
        description: Job ID for tracking the addition process
        example: deadbeef
        format: hex
        type: string
    type: object
  apicommon.CensusParticipantsResponse:
    properties:
      censusId:
        description: Unique identifier for the census
        type: string
      memberIds:
        description: List of member IDs of the participants
        items:
          type: string
        type: array
    type: object
  apicommon.CheckBundleParticipantsRequest:
    properties:
      fieldName:
        type: string
      processID:
        example: deadbeef
        format: hex
        type: string
      value:
        type: string
    type: object
  apicommon.CheckBundleParticipantsResponse:
    properties:
      participants:
        items:
          $ref: '#/definitions/apicommon.CheckBundleParticipantsResponseEntry'
        type: array
    type: object
  apicommon.CheckBundleParticipantsResponseEntry:
    properties:
      email:
        type: string
      hasVoted:
        type: boolean
      memberId:
        type: string
      memberNumber:
        type: string
      name:
        type: string
      surname:
        type: string
    type: object
  apicommon.CreateAPIKeyRequest:
    properties:
      expiresAt:
        description: Optional expiration; when set, the key stops working after this
          time.
        type: string
      label:
        description: Human-readable label to identify the key.
        type: string
      scopes:
        description: Scopes the key is allowed to use (must be a subset of the assignable
          scopes).
        items:
          type: string
        type: array
    type: object
  apicommon.CreateAPIKeyResponse:
    properties:
      createdAt:
        type: string
      createdBy:
        type: string
      expiresAt:
        type: string
      id:
        type: string
      label:
        type: string
      lastUsedAt:
        type: string
      prefix:
        type: string
      revoked:
        type: boolean
      scopes:
        items:
          type: string
        type: array
      secret:
        description: Secret is the full API key, shown only at creation time.
        type: string
    type: object
  apicommon.CreateCensusRequest:
    properties:
      authFields:
        description: Optional for defining which member data should be used for authentication
        items:
          $ref: '#/definitions/db.OrgMemberAuthField'
        type: array
      orgAddress:
        description: Organization address
        items:
          type: integer
        type: array
      twoFaFields:
        description: Optional for defining which member data should be used for two-factor
          authentication
        items:
          $ref: '#/definitions/db.OrgMemberTwoFaField'
        type: array
    type: object
  apicommon.CreateCensusResponse:
    properties:
      id:
        description: Unique identifier for the census
        type: string
    type: object
  apicommon.CreateManagedOrganizationRequest:
    properties:
      active:
        description: Whether the organization is active
        type: boolean
      address:
        description: The organization's blockchain address
        items:
          type: integer
        type: array
      color:
        description: The organization's brand color in hex format
        type: string
      communications:
        description: Whether the organization has enabled communications
        type: boolean
      counters:
        allOf:
        - $ref: '#/definitions/apicommon.SubscriptionUsage'
        description: Usage counters for the organization
      country:
        description: The country where the organization is based
        type: string
      createdAt:
        description: Creation timestamp in RFC3339 format
        type: string
      integrator:
        description: |-
          Whether to subscribe the new organization to the free integrator plan at
          creation time (opt-in). Used by the integrator portal so a newly created org
          becomes an integrator on the free tier with no checkout. Default false uses
          the regular default plan.
        type: boolean
      meta:
        additionalProperties: {}
        description: Arbitrary key value fields with metadata regarding the organization
        type: object
      ownerEmail:
        description: OwnerEmail optionally assigns an existing user as the managed
          org's creator/admin.
        type: string
      parent:
        allOf:
        - $ref: '#/definitions/apicommon.OrganizationInfo'
        description: Parent organization if this is a sub-organization
      size:
        description: The size category of the organization
        type: string
      subdomain:
        description: The organization's subdomain
        type: string
      subscription:
        allOf:
        - $ref: '#/definitions/apicommon.SubscriptionDetails'
        description: Subscription details for the organization
      timezone:
        description: The organization's timezone
        type: string
      type:
        description: The type of organization
        type: string
      website:
        description: The organization's website URL
        type: string
    type: object
  apicommon.CreateOrganizationMemberGroupRequest:
    properties:
      description:
        description: Description of the group
        type: string
      includeAllMembers:
        description: Include all members of the organization in the group
        type: boolean
      memberIds:
        description: The IDs of the members to add to the group (optional if IncludeAllMembers
          is true)
        items:
          type: string
        type: array
      title:
        description: Title of the group
        type: string
    type: object
  apicommon.CreateOrganizationRequest:
    properties:
      active:
        description: Whether the organization is active
        type: boolean
      address:
        description: The organization's blockchain address
        items:
          type: integer
        type: array
      color:
        description: The organization's brand color in hex format
        type: string
      communications:
        description: Whether the organization has enabled communications
        type: boolean
      counters:
        allOf:
        - $ref: '#/definitions/apicommon.SubscriptionUsage'
        description: Usage counters for the organization
      country:
        description: The country where the organization is based
        type: string
      createdAt:
        description: Creation timestamp in RFC3339 format
        type: string
      integrator:
        description: |-
          Whether to subscribe the new organization to the free integrator plan at
          creation time (opt-in). Used by the integrator portal so a newly created org
          becomes an integrator on the free tier with no checkout. Default false uses
          the regular default plan.
        type: boolean
      meta:
        additionalProperties: {}
        description: Arbitrary key value fields with metadata regarding the organization
        type: object
      parent:
        allOf:
        - $ref: '#/definitions/apicommon.OrganizationInfo'
        description: Parent organization if this is a sub-organization
      provisionAccount:
        description: |-
          Whether to provision the organization's on-chain account at creation
          time (opt-in, eager). Default false preserves the legacy two-step flow
          where the account is created later by the SDK.
        type: boolean
      size:
        description: The size category of the organization
        type: string
      subdomain:
        description: The organization's subdomain
        type: string
      subscription:
        allOf:
        - $ref: '#/definitions/apicommon.SubscriptionDetails'
        description: Subscription details for the organization
      timezone:
        description: The organization's timezone
        type: string
      type:
        description: The type of organization
        type: string
      website:
        description: The organization's website URL
        type: string
    type: object
  apicommon.CreateOrganizationTicketRequest:
    properties:
      description:
        description: Body of the ticket
        type: string
      title:
        description: Title of the ticket
        type: string
      type:
        description: Type of the ticket to create (definded externally)
        type: string
    type: object
  apicommon.CreateProcessBundleRequest:
    properties:
      censusId:
        description: Census ID
        type: string
      processes:
        description: |-
          List of processes to include in the bundle. Each entry is either the 24-hex ProcessID or the
          64-hex on-chain election id.
        items:
          type: string
        type: array
    type: object
  apicommon.CreateProcessBundleResponse:
    properties:
      root:
        description: Merkle root of the process bundle
        example: deadbeef
        format: hex
        type: string
      uri:
        description: URI of the created process bundle
        type: string
    type: object
  apicommon.CreateProcessRequest:
    properties:
      address:
        description: Vochain ID/Address of the process
        example: deadbeef
        format: hex
        type: string
      censusId:
        description: Census ID
        example: deadbeef
        format: hex
        type: string
      electionParams:
        allOf:
        - $ref: '#/definitions/db.ElectionParams'
        description: Optional high-level election parameters (used later at publish
          time)
      metadata:
        additionalProperties: {}
        description: |-
          Additional metadata for the process
          Can be any key-value pairs
        type: object
      orgAddress:
        description: Organization address
        items:
          type: integer
        type: array
    type: object
  apicommon.DeleteManagedOrganizationResponse:
    properties:
      address:
        type: string
    type: object
  apicommon.DeleteMembersRequest:
    properties:
      all:
        description: Delete all members of the organization
        type: boolean
      ids:
        description: List of member internal ids numbers to delete (optional if All
          is true)
        items:
          type: string
        type: array
    type: object
  apicommon.DeleteMembersResponse:
    properties:
      count:
        description: Number of members deleted
        type: integer
    type: object
  apicommon.EnqueuedResponse:
    properties:
      jobId:
        description: Opaque job id; poll GET /jobs/{jobId} for the outcome
        example: a1b2c3
        type: string
    type: object
  apicommon.IntegratorInfoResponse:
    properties:
      enabled:
        type: boolean
      limits:
        $ref: '#/definitions/apicommon.IntegratorLimits'
      usage:
        $ref: '#/definitions/apicommon.IntegratorUsage'
    type: object
  apicommon.IntegratorLimits:
    properties:
      maxEmails:
        type: integer
      maxManagedOrgs:
        type: integer
      maxManagedProcesses:
        type: integer
      maxSMS:
        type: integer
      maxVotes:
        type: integer
    type: object
  apicommon.IntegratorUsage:
    properties:
      managedOrgs:
        type: integer
      managedProcesses:
        type: integer
      sentEmails:
        type: integer
      sentSMS:
        type: integer
      sentVotes:
        type: integer
    type: object
  apicommon.JobInfo:
    properties:
      added:
        description: Items successfully processed
        type: integer
      completed:
        description: Whether the job is completed
        type: boolean
      completedAt:
        description: Job completion timestamp (zero if not completed)
        type: string
      createdAt:
        description: Job creation timestamp
        type: string
      errors:
        description: List of errors encountered
        items:
          type: string
        type: array
      jobId:
        description: Unique job identifier
        type: string
      total:
        description: Total items to process
        type: integer
      type:
        allOf:
        - $ref: '#/definitions/db.JobType'
        description: Type of job
    type: object
  apicommon.JobStatusResponse:
    properties:
      error:
        type: string
      jobId:
        type: string
      result:
        $ref: '#/definitions/db.JobResult'
      status:
        $ref: '#/definitions/db.JobStatus'
      type:
        $ref: '#/definitions/db.JobType'
    type: object
  apicommon.JobsResponse:
    properties:
      jobs:
        description: List of jobs
        items:
          $ref: '#/definitions/apicommon.JobInfo'
        type: array
      pagination:
        allOf:
        - $ref: '#/definitions/apicommon.Pagination'
        description: Pagination fields
    type: object
  apicommon.ListAPIKeysResponse:
    properties:
      apiKeys:
        items:
          $ref: '#/definitions/apicommon.APIKeyInfo'
        type: array
    type: object
  apicommon.ListManagedOrganizations:
    properties:
      organizations:
        items:
          $ref: '#/definitions/apicommon.OrganizationInfo'
        type: array
      pagination:
        $ref: '#/definitions/apicommon.Pagination'
    type: object
  apicommon.ListOrganizationBundles:
    properties:
      bundles:
        description: List of organization bundles
        items:
          $ref: '#/definitions/apicommon.OrganizationBundle'
        type: array
      pagination:
        allOf:
        - $ref: '#/definitions/apicommon.Pagination'
        description: Pagination fields
    type: object
  apicommon.ListOrganizationMemberGroupResponse:
    properties:
      members:
        description: List of organization group members
        items:
          $ref: '#/definitions/apicommon.OrgMember'
        type: array
      pagination:
        allOf:
        - $ref: '#/definitions/apicommon.Pagination'
        description: Pagination fields
    type: object
  apicommon.ListOrganizationProcesses:
    properties:
      pagination:
        allOf:
        - $ref: '#/definitions/apicommon.Pagination'
        description: Pagination fields
      processes:
        description: List of organization processes
        items:
          $ref: '#/definitions/db.Process'
        type: array
    type: object
  apicommon.LoginResponse:
    properties:
      expirity:
        description: Token expiration time
        type: string
      token:
        description: JWT authentication token
        type: string
    type: object
  apicommon.MessageSignature:
    properties:
      address:
        description: Blockchain address
        example: deadbeef
        format: hex
        type: string
      payload:
        description: Message payload bytes
        example: aGVsbG8gd29ybGQ=
        format: base64
        type: string
      signature:
        description: Cryptographic signature
        example: deadbeef
        format: hex
        type: string
    type: object
  apicommon.OAuthLinkRequest:
    properties:
      address:
        description: The address of the user
        type: string
      oauthSignature:
        description: The signature made by the OAuth service on top of the user email
        type: string
      provider:
        description: OAuth provider name (google, github, facebook)
        type: string
      userOAuthSignature:
        description: The signature made by the user on top of the oauth signature
        type: string
    type: object
  apicommon.OAuthLoginRequest:
    properties:
      address:
        description: The address of the user
        type: string
      email:
        description: User email address
        type: string
      firstName:
        description: User first name
        type: string
      lastName:
        description: User last name
        type: string
      oauthSignature:
        description: The signature made by the OAuth service on top of the user email
        type: string
      provider:
        description: OAuth provider name (google, github, facebook)
        type: string
      userOAuthSignature:
        description: The signature made by the user on on top of the oauth signature
        type: string
    type: object
  apicommon.OAuthLoginResponse:
    properties:
      expirity:
        description: Token expiration time
        type: string
      registered:
        description: Whether the user had to be  registered
        type: boolean
      token:
        description: JWT authentication token
        type: string
    type: object
  apicommon.OrgMember:
    properties:
      birthDate:
        description: Member's date of birth in format YYYY-MM-DD
        type: string
      email:
        description: Member's email address
        type: string
      id:
        description: Member's internal unique internal ID
        type: string
      memberNumber:
        description: Unique member number as defined by the organization
        type: string
      name:
        description: Member's name
        type: string
      nationalId:
        description: Member's National ID No
        type: string
      other:
        additionalProperties: {}
        description: Additional custom fields
        type: object
      password:
        description: Member's password (for authentication)
        type: string
      phone:
        description: Member's phone number
        type: string
      surname:
        description: Member's surname
        type: string
      weight:
        description: Member's census weight
        type: string
    type: object
  apicommon.OrganizationAddMetaRequest:
    properties:
      meta:
        additionalProperties: {}
        description: Set of key-value pairs to add or update in the organization's
          meta information
        type: object
    type: object
  apicommon.OrganizationAddresses:
    properties:
      addresses:
        description: List of organization blockchain addresses
        items:
          items:
            type: integer
          type: array
        type: array
    type: object
  apicommon.OrganizationBundle:
    properties:
      bundleId:
        description: The ID of the bundle
        type: string
      primaryProcessId:
        description: |-
          The ID of the primary process which identifies the set of processes in
          the bundle, no matter how many (one or more)
        type: string
      processes:
        description: The list of processes IDs in the bundle
        items:
          type: string
        type: array
    type: object
  apicommon.OrganizationCensus:
    properties:
      authFields:
        description: Optional for defining which member data should be used for authentication
        items:
          $ref: '#/definitions/db.OrgMemberAuthField'
        type: array
      censusId:
        description: Unique identifier for the census
        type: string
      groupID:
        description: Optional for creating a census based on an organization member
          group
        type: string
      orgAddress:
        description: Organization address
        items:
          type: integer
        type: array
      size:
        description: Size of the census
        type: integer
      twoFaFields:
        description: Optional for defining which member data should be used for two-factor
          authentication
        items:
          $ref: '#/definitions/db.OrgMemberTwoFaField'
        type: array
      type:
        allOf:
        - $ref: '#/definitions/db.CensusType'
        description: Type of census
      weighted:
        description: Weighted indicates if the census uses weighted voting
        type: boolean
    type: object
  apicommon.OrganizationCensuses:
    properties:
      censuses:
        description: List of organization censuses
        items:
          $ref: '#/definitions/apicommon.OrganizationCensus'
        type: array
    type: object
  apicommon.OrganizationDeleteMetaRequest:
    properties:
      keys:
        description: List of keys to delete from the organization's meta information
        items:
          type: string
        type: array
    type: object
  apicommon.OrganizationInfo:
    properties:
      active:
        description: Whether the organization is active
        type: boolean
      address:
        description: The organization's blockchain address
        items:
          type: integer
        type: array
      color:
        description: The organization's brand color in hex format
        type: string
      communications:
        description: Whether the organization has enabled communications
        type: boolean
      counters:
        allOf:
        - $ref: '#/definitions/apicommon.SubscriptionUsage'
        description: Usage counters for the organization
      country:
        description: The country where the organization is based
        type: string
      createdAt:
        description: Creation timestamp in RFC3339 format
        type: string
      integrator:
        description: |-
          Whether to subscribe the new organization to the free integrator plan at
          creation time (opt-in). Used by the integrator portal so a newly created org
          becomes an integrator on the free tier with no checkout. Default false uses
          the regular default plan.
        type: boolean
      meta:
        additionalProperties: {}
        description: Arbitrary key value fields with metadata regarding the organization
        type: object
      parent:
        allOf:
        - $ref: '#/definitions/apicommon.OrganizationInfo'
        description: Parent organization if this is a sub-organization
      size:
        description: The size category of the organization
        type: string
      subdomain:
        description: The organization's subdomain
        type: string
      subscription:
        allOf:
        - $ref: '#/definitions/apicommon.SubscriptionDetails'
        description: Subscription details for the organization
      timezone:
        description: The organization's timezone
        type: string
      type:
        description: The type of organization
        type: string
      website:
        description: The organization's website URL
        type: string
    type: object
  apicommon.OrganizationInvite:
    properties:
      email:
        description: Email address of the invitee
        type: string
      expiration:
        description: Expiration time of the invitation
        type: string
      id:
        description: Unique identifier for the invitation
        type: string
      role:
        allOf:
        - $ref: '#/definitions/db.UserRole'
        description: Role to be assigned to the invitee
    type: object
  apicommon.OrganizationInviteList:
    properties:
      pending:
        description: List of pending invitations
        items:
          $ref: '#/definitions/apicommon.OrganizationInvite'
        type: array
    type: object
  apicommon.OrganizationMemberGroupInfo:
    properties:
      censusIds:
        description: List of census IDs associated with the group
        items:
          type: string
        type: array
      createdAt:
        description: Creation timestamp
        type: string
      description:
        description: Description of the group
        type: string
      id:
        description: Unique identifier for the group
        type: string
      isAutoGroup:
        description: |-
          IsAutoGroup indicates this is the auto-generated "All members" group.
          It cannot be deleted and its membership cannot be manually modified.
        type: boolean
      memberIds:
        description: List of member IDs in the group
        items:
          type: string
        type: array
      membersCount:
        description: Count of members in the group
        type: integer
      title:
        description: Title of the group
        type: string
      updatedAt:
        description: Last updated timestamp
        type: string
    type: object
  apicommon.OrganizationMemberGroupsResponse:
    properties:
      groups:
        description: List of organization member groups
        items:
          $ref: '#/definitions/apicommon.OrganizationMemberGroupInfo'
        type: array
      pagination:
        allOf:
        - $ref: '#/definitions/apicommon.Pagination'
        description: Pagination fields
    type: object
  apicommon.OrganizationMembersResponse:
    properties:
      members:
        description: Total members in the organization
        items:
          $ref: '#/definitions/apicommon.OrgMember'
        type: array
      pagination:
        allOf:
        - $ref: '#/definitions/apicommon.Pagination'
        description: Pagination fields
    type: object
  apicommon.OrganizationMetaResponse:
    properties:
      meta:
        additionalProperties: {}
        description: Meta information of the organization
        type: object
    type: object
  apicommon.OrganizationRole:
    properties:
      name:
        description: Human-readable name of the role
        type: string
      organizationWritePermission:
        description: Whether this role has organization write permission
        type: boolean
      processWritePermission:
        description: Whether this role has process write permission
        type: boolean
      role:
        description: Role identifier
        type: string
    type: object
  apicommon.OrganizationRoleList:
    properties:
      roles:
        description: List of organization roles
        items:
          $ref: '#/definitions/apicommon.OrganizationRole'
        type: array
    type: object
  apicommon.OrganizationSubscriptionInfo:
    properties:
      plan:
        allOf:
        - $ref: '#/definitions/apicommon.SubscriptionPlan'
        description: Subscription plan details
      subscriptionDetails:
        allOf:
        - $ref: '#/definitions/apicommon.SubscriptionDetails'
        description: Subscription details
      usage:
        allOf:
        - $ref: '#/definitions/apicommon.SubscriptionUsage'
        description: Current usage metrics
    type: object
  apicommon.OrganizationType:
    properties:
      name:
        description: Human-readable name of the type
        type: string
      type:
        description: Type identifier
        type: string
    type: object
  apicommon.OrganizationTypeList:
    properties:
      types:
        description: List of organization types
        items:
          $ref: '#/definitions/apicommon.OrganizationType'
        type: array
    type: object
  apicommon.OrganizationUser:
    properties:
      info:
        allOf:
        - $ref: '#/definitions/apicommon.UserInfo'
        description: User information
      role:
        description: The role of the user in the organization
        type: string
    type: object
  apicommon.OrganizationUsers:
    properties:
      users:
        description: List of organization users
        items:
          $ref: '#/definitions/apicommon.OrganizationUser'
        type: array
    type: object
  apicommon.Pagination:
    properties:
      currentPage:
        type: integer
      lastPage:
        type: integer
      nextPage:
        type: integer
      previousPage:
        type: integer
      totalItems:
        type: integer
    type: object
  apicommon.ProcessBundleInfo:
    properties:
      census:
        allOf:
        - $ref: '#/definitions/db.Census'
        description: The census associated with this bundle
      chainId:
        type: string
      id:
        description: Unique identifier for the bundle
        type: string
      orgAddress:
        description: The organization that owns this bundle
        items:
          type: integer
        type: array
      processes:
        description: Array of process addresses included in this bundle
        example:
        - deadbeef
        items:
          format: hex
          type: string
        type: array
    type: object
  apicommon.ProcessInfo:
    properties:
      address:
        example: deadbeef
        format: hex
        type: string
      census:
        $ref: '#/definitions/db.Census'
      chainId:
        type: string
      electionParams:
        $ref: '#/definitions/db.ElectionParams'
      encryptionKeys:
        description: |-
          EncryptionKeys holds the on-chain encryption public keys of an encrypted
          (secretUntilTheEnd) election. They are resolved lazily on read and cached here once
          the keykeepers have published them (immutable thereafter). Unset/omitted for
          non-encrypted elections and for encrypted ones whose keys are not yet published.
        items:
          $ref: '#/definitions/db.EncryptionKey'
        type: array
      id:
        type: string
      metadata:
        additionalProperties: {}
        type: object
      metadataURL:
        description: |-
          MetadataURL is the generic reference to this process's canonical ElectionMetadata
          document. http(s) references are fetched — locally when they point at this service's
          object storage (including a relative "/storage/{name}" reference), otherwise via an
          external request; ipfs references are resolved via the Vochain and then cached
          locally. Bootstrapped from the on-chain pointer on first read when unset. Unset for
          unpublished drafts, and omitted from JSON in that case (omitempty).
        type: string
      orgAdress:
        items:
          type: integer
        type: array
      publishedAt:
        type: string
      status:
        type: string
    type: object
  apicommon.ProcessResultsResponse:
    properties:
      endDate:
        type: string
      finalResults:
        type: boolean
      results:
        items:
          items:
            type: string
          type: array
        type: array
      startDate:
        type: string
      status:
        type: string
      voteCount:
        type: integer
    type: object
  apicommon.PublishCensusGroupRequest:
    properties:
      authFields:
        description: |-
          Member data fields used for authentication (e.g. nationalId, birthDate). At least one
          of authFields or twoFaFields must be provided; supplying only authFields publishes an
          auth-only (no OTP) CSP census. A request with both empty is rejected (ErrCensusTypeNotFound).
        items:
          $ref: '#/definitions/db.OrgMemberAuthField'
        type: array
      twoFaFields:
        description: |-
          Member data fields used for two-factor authentication (email and/or phone, sent as an OTP
          challenge). At least one of authFields or twoFaFields must be provided.
        items:
          $ref: '#/definitions/db.OrgMemberTwoFaField'
        type: array
      weighted:
        description: Indicates if the census is weighted
        type: boolean
    type: object
  apicommon.PublishProcessResponse:
    properties:
      address:
        description: On-chain process id (Vochain election id)
        example: deadbeef
        format: hex
        type: string
      status:
        description: Process status (e.g. "READY")
        type: string
    type: object
  apicommon.PublishedCensusResponse:
    properties:
      root:
        description: Merkle root of the census
        example: deadbeef
        format: hex
        type: string
      size:
        description: Size of the published census
        type: integer
      uri:
        description: URI of the published census
        type: string
    type: object
  apicommon.RelayVoteRequest:
    properties:
      txPayload:
        description: Hex of a marshaled models.SignedTx whose inner Tx is a Vote
        example: deadbeef
        format: hex
        type: string
    type: object
  apicommon.SetProcessStatusRequest:
    properties:
      status:
        description: 'One of: ready, paused, ended, canceled'
        example: paused
        type: string
    type: object
  apicommon.SubscriptionCheckout:
    properties:
      address:
        description: Organization address
        items:
          type: integer
        type: array
      billingPeriod:
        description: Billing period (e.g., "month" or "year")
        type: string
      locale:
        description: Locale for the checkout page
        type: string
      lookupKey:
        description: Plan lookup key (the plan's Stripe product ID)
        type: string
      returnURL:
        description: URL to return to after checkout
        type: string
    type: object
  apicommon.SubscriptionDetails:
    properties:
      active:
        description: Whether the subscription is active
        type: boolean
      email:
        description: Email associated with the subscription
        type: string
      lastPaymentDate:
        description: Date of the last payment
        type: string
      planId:
        description: ID of the subscription plan (its Stripe product ID)
        type: string
      renewalDate:
        description: Date when the subscription will renew
        type: string
      startDate:
        description: Date when the subscription started
        type: string
    type: object
  apicommon.SubscriptionFeatures:
    properties:
      2FAemail:
        description: Two-factor authentication email limit
        type: integer
      2FAsms:
        description: Two-factor authentication sms limit
        type: integer
      anonymous:
        description: Whether anonymous voting is available
        type: boolean
      emailReminder:
        description: Whether email reminders are available
        type: boolean
      liveResults:
        description: Whether live results are available
        type: boolean
      liveStreaming:
        description: Whether live streaming is available
        type: boolean
      overwrite:
        description: Whether census overwrite is allowed
        type: boolean
      personalization:
        description: Whether UI personalization is available
        type: boolean
      phoneSupport:
        description: Whether eligible for phone support
        type: boolean
      whiteLabel:
        description: Whether white labeling is available
        type: boolean
    type: object
  apicommon.SubscriptionIntegratorLimits:
    properties:
      maxManagedOrgs:
        description: |-
          Maximum number of organizations the integrator may manage. The aggregate
          process and census-size caps across managed orgs come from the plan's
          top-level limits (maxProcesses / maxCensus).
        type: integer
    type: object
  apicommon.SubscriptionPlan:
    properties:
      default:
        description: Whether this is the default plan
        type: boolean
      features:
        allOf:
        - $ref: '#/definitions/apicommon.SubscriptionFeatures'
        description: Features available in this plan
      id:
        description: Unique identifier for the plan (its Stripe product ID)
        type: string
      integratorLimits:
        allOf:
        - $ref: '#/definitions/apicommon.SubscriptionIntegratorLimits'
        description: Integrator limits for this plan (zero when the plan is not an
          integrator plan)
      monthlyPrice:
        description: Monthly price
        type: integer
      name:
        description: Human-readable name of the plan
        type: string
      organization:
        allOf:
        - $ref: '#/definitions/apicommon.SubscriptionPlanLimits'
        description: Organization limits for this plan
      stripeMonthlyPriceId:
        description: Stripe monthly price ID
        type: string
      stripeYearlyPriceId:
        description: Stripe yearly price ID
        type: string
      votingTypes:
        allOf:
        - $ref: '#/definitions/apicommon.SubscriptionVotingTypes'
        description: Voting types available in this plan
      yearlyPrice:
        description: Yearly price
        type: integer
    type: object
  apicommon.SubscriptionPlanLimits:
    properties:
      customPlan:
        description: Whether this is a custom plan
        type: boolean
      customURL:
        description: Whether custom URLs are allowed
        type: boolean
      drafts:
        description: How many draft processes are allowed
        type: integer
      maxCensus:
        description: Maximum number of census allowed
        type: integer
      maxDaysDuration:
        description: Maximum duration of voting processes in days
        type: integer
      maxProcesses:
        description: Maximum number of voting processes allowed
        type: integer
      maxVotes:
        description: Maximum number of votes that may be relayed; 0 means unlimited
        type: integer
      subOrgs:
        description: Maximum number of sub-organizations allowed
        type: integer
      teamMembers:
        description: Maximum number of users allowed
        type: integer
    type: object
  apicommon.SubscriptionUsage:
    properties:
      processes:
        description: Number of voting processes created
        type: integer
      sentEmails:
        description: Number of emails sent
        type: integer
      sentSMS:
        description: Number of SMS messages sent
        type: integer
      sentVotes:
        description: Number of votes relayed
        type: integer
      subOrgs:
        description: Number of sub-organizations created
        type: integer
      users:
        description: Number of users in the organization
        type: integer
    type: object
  apicommon.SubscriptionVotingTypes:
    properties:
      approval:
        description: Whether approval voting is available
        type: boolean
      cumulative:
        description: Whether cumulative voting is available
        type: boolean
      multiple:
        description: Whether multiple choice voting is available
        type: boolean
      ranked:
        description: Whether ranked choice voting is available
        type: boolean
      single:
        description: Whether single choice voting is available
        type: boolean
      weighted:
        description: Whether weighted voting is available
        type: boolean
    type: object
  apicommon.TransactionData:
    properties:
      address:
        description: Blockchain address
        example: deadbeef
        format: hex
        type: string
      txPayload:
        description: Transaction payload bytes
        example: aGVsbG8gd29ybGQ=
        format: base64
        type: string
    type: object
  apicommon.UpdateOrganizationMemberGroupsRequest:
    properties:
      addMembers:
        description: The IDs of the members to add to the group
        items:
          type: string
        type: array
      description:
        description: Updated Description
        type: string
      removeMembers:
        description: The IDs of the members to remove from the group
        items:
          type: string
        type: array
      title:
        description: Updated Title
        type: string
    type: object
  apicommon.UpdateOrganizationUserRoleRequest:
    properties:
      role:
        description: The new role to assign to the user
        type: string
    type: object
  apicommon.UpdateProcessRequest:
    properties:
      address:
        description: Vochain ID/Address of the process
        example: deadbeef
        format: hex
        type: string
      censusId:
        description: Census ID
        example: deadbeef
        format: hex
        type: string
      electionParams:
        allOf:
        - $ref: '#/definitions/db.ElectionParams'
        description: Optional high-level election parameters (used later at publish
          time)
      metadata:
        additionalProperties: {}
        description: |-
          Additional metadata for the process
          Can be any key-value pairs
        type: object
    type: object
  apicommon.UserInfo:
    properties:
      email:
        description: User's email address
        type: string
      firstName:
        description: User's first name
        type: string
      hasPassword:
        description: Whether the user has a password set (true if not OAuth-only)
        type: boolean
      id:
        description: User ID as generated by the backend
        type: integer
      isIntegrator:
        description: |-
          Whether the user belongs to an integrator organization (integrators have a
          single org). Lets clients learn integrator status straight from the login
          flow without an extra request. Populated by GET /users/me.
        type: boolean
      lastName:
        description: User's last name
        type: string
      organizations:
        description: Organizations the user belongs to
        items:
          $ref: '#/definitions/apicommon.UserOrganization'
        type: array
      password:
        description: User's password (not returned in responses)
        type: string
      providers:
        description: List of OAuth providers linked to this account (e.g., ["google",
          "github"])
        items:
          type: string
        type: array
      verified:
        description: Whether the user's email is verified
        type: boolean
    type: object
  apicommon.UserOrganization:
    properties:
      organization:
        allOf:
        - $ref: '#/definitions/apicommon.OrganizationInfo'
        description: Organization information
      role:
        description: The role of the user in the organization
        type: string
    type: object
  apicommon.UserPasswordReset:
    properties:
      code:
        description: Password reset code
        type: string
      email:
        description: User's email address
        type: string
      newPassword:
        description: New password
        type: string
    type: object
  apicommon.UserPasswordUpdate:
    properties:
      newPassword:
        description: New password
        type: string
      oldPassword:
        description: Current password
        type: string
    type: object
  apicommon.UserVerification:
    properties:
      code:
        description: Verification code
        type: string
      email:
        description: User's email address
        type: string
      expiration:
        description: Expiration time of the verification code
        type: string
      valid:
        description: Whether the verification is valid
        type: boolean
    type: object
  apicommon.ValidateMemberGroupRequest:
    properties:
      authFields:
        description: Defines which member data should be used for authentication
        items:
          $ref: '#/definitions/db.OrgMemberAuthField'
        type: array
      twoFaFields:
        description: Defines which member data should be used for two-factor authentication
        items:
          $ref: '#/definitions/db.OrgMemberTwoFaField'
        type: array
    type: object
  db.Census:
    properties:
      authFields:
        items:
          $ref: '#/definitions/db.OrgMemberAuthField'
        type: array
      createdAt:
        type: string
      groupId:
        type: string
      id:
        type: string
      orgAddress:
        items:
          type: integer
        type: array
      published:
        $ref: '#/definitions/db.PublishedCensus'
      size:
        type: integer
      twoFaFields:
        items:
          $ref: '#/definitions/db.OrgMemberTwoFaField'
        type: array
      type:
        $ref: '#/definitions/db.CensusType'
      updatedAt:
        type: string
      weighted:
        type: boolean
    type: object
  db.CensusType:
    enum:
    - auth
    - mail
    - sms
    - sms_or_mail
    type: string
    x-enum-varnames:
    - CensusTypeAuthOnly
    - CensusTypeMail
    - CensusTypeSMS
    - CensusTypeSMSorMail
  db.Choice:
    properties:
      title:
        $ref: '#/definitions/db.MultiLangString'
      value:
        type: integer
    type: object
  db.ElectionParams:
    properties:
      description:
        $ref: '#/definitions/db.MultiLangString'
      electionType:
        $ref: '#/definitions/db.ElectionType'
      endDate:
        type: string
      header:
        type: string
      maxCensusSize:
        type: integer
      questions:
        items:
          $ref: '#/definitions/db.Question'
        type: array
      startDate:
        type: string
      streamUri:
        type: string
      title:
        $ref: '#/definitions/db.MultiLangString'
      type:
        $ref: '#/definitions/db.ElectionTypeMetadata'
      voteType:
        $ref: '#/definitions/db.VoteType'
    type: object
  db.ElectionType:
    properties:
      anonymous:
        type: boolean
      autostart:
        type: boolean
      dynamicCensus:
        type: boolean
      interruptible:
        type: boolean
      secretUntilTheEnd:
        type: boolean
    type: object
  db.ElectionTypeMetadata:
    properties:
      name:
        type: string
      properties: {}
    type: object
  db.EncryptionKey:
    properties:
      index:
        type: integer
      key:
        example: deadbeef
        format: hex
        type: string
    type: object
  db.Features:
    properties:
      2FAemail:
        type: integer
      2FAsms:
        type: integer
      anonymous:
        type: boolean
      emailReminder:
        type: boolean
      liveResults:
        type: boolean
      liveStreaming:
        type: boolean
      overwrite:
        type: boolean
      personalization:
        type: boolean
      phoneSupport:
        type: boolean
      whiteLabel:
        type: boolean
    type: object
  db.IntegratorLimits:
    properties:
      maxManagedOrgs:
        type: integer
    type: object
  db.JobResult:
    properties:
      address:
        example: deadbeef
        type: string
      status:
        type: string
      voteID:
        example: deadbeef
        type: string
    type: object
  db.JobStatus:
    enum:
    - pending
    - completed
    - failed
    type: string
    x-enum-varnames:
    - JobStatusPending
    - JobStatusCompleted
    - JobStatusFailed
  db.JobType:
    enum:
    - org_members
    - census_participants
    - publish_process
    - set_process_status
    - relay_vote
    type: string
    x-enum-varnames:
    - JobTypeOrgMembers
    - JobTypeCensusParticipants
    - JobTypePublishProcess
    - JobTypeSetProcessStatus
    - JobTypeRelayVote
  db.MultiLangString:
    additionalProperties:
      type: string
    type: object
  db.OrgMemberAuthField:
    enum:
    - name
    - surname
    - memberNumber
    - nationalId
    - birthDate
    type: string
    x-enum-varnames:
    - OrgMemberAuthFieldsName
    - OrgMemberAuthFieldsSurname
    - OrgMemberAuthFieldsMemberNumber
    - OrgMemberAuthFieldsNationalID
    - OrgMemberAuthFieldsBirthDate
  db.OrgMemberTwoFaField:
    enum:
    - email
    - phone
    type: string
    x-enum-varnames:
    - OrgMemberTwoFaFieldEmail
    - OrgMemberTwoFaFieldPhone
  db.Plan:
    properties:
      default:
        type: boolean
      features:
        $ref: '#/definitions/db.Features'
      freeTrialDays:
        type: integer
      id:
        type: string
      integratorLimits:
        $ref: '#/definitions/db.IntegratorLimits'
      monthlyPrice:
        type: integer
      name:
        type: string
      organization:
        $ref: '#/definitions/db.PlanLimits'
      public:
        description: |-
          Public reports whether the plan is listed on the public /plans catalog. Private plans
          (custom per-customer contracts and the internal free integrator tier) are hidden from
          the listing but remain visible to their own subscriber via the subscription payload.
        type: boolean
      stripeMonthlyPriceID:
        type: string
      stripeYearlyPriceID:
        type: string
      votingTypes:
        $ref: '#/definitions/db.VotingTypes'
      yearlyPrice:
        type: integer
    type: object
  db.PlanLimits:
    properties:
      customPlan:
        type: boolean
      customURL:
        type: boolean
      drafts:
        type: integer
      maxCensus:
        type: integer
      maxDaysDuration:
        description: Max process duration in days
        type: integer
      maxProcesses:
        type: integer
      maxVotes:
        description: |-
          Max votes that may be relayed; 0 means unlimited. For managed orgs this is the
          integrator's shared pool, summed across all its managed orgs.
        type: integer
      subOrgs:
        type: integer
      teamMembers:
        type: integer
    type: object
  db.Process:
    properties:
      address:
        example: deadbeef
        format: hex
        type: string
      census:
        $ref: '#/definitions/db.Census'
      electionParams:
        $ref: '#/definitions/db.ElectionParams'
      encryptionKeys:
        description: |-
          EncryptionKeys holds the on-chain encryption public keys of an encrypted
          (secretUntilTheEnd) election. They are resolved lazily on read and cached here once
          the keykeepers have published them (immutable thereafter). Unset/omitted for
          non-encrypted elections and for encrypted ones whose keys are not yet published.
        items:
          $ref: '#/definitions/db.EncryptionKey'
        type: array
      id:
        type: string
      metadata:
        additionalProperties: {}
        type: object
      metadataURL:
        description: |-
          MetadataURL is the generic reference to this process's canonical ElectionMetadata
          document. http(s) references are fetched — locally when they point at this service's
          object storage (including a relative "/storage/{name}" reference), otherwise via an
          external request; ipfs references are resolved via the Vochain and then cached
          locally. Bootstrapped from the on-chain pointer on first read when unset. Unset for
          unpublished drafts, and omitted from JSON in that case (omitempty).
        type: string
      orgAdress:
        items:
          type: integer
        type: array
      publishedAt:
        type: string
      status:
        type: string
    type: object
  db.PublishedCensus:
    properties:
      createdAt:
        type: string
      root:
        items:
          type: integer
        type: array
      uri:
        type: string
    type: object
  db.Question:
    properties:
      choices:
        items:
          $ref: '#/definitions/db.Choice'
        type: array
      description:
        $ref: '#/definitions/db.MultiLangString'
      title:
        $ref: '#/definitions/db.MultiLangString'
    type: object
  db.UserRole:
    enum:
    - admin
    - manager
    - viewer
    type: string
    x-enum-varnames:
    - AdminRole
    - ManagerRole
    - ViewerRole
  db.VoteType:
    properties:
      costExponent:
        type: integer
      costFromWeight:
        type: boolean
      maxCount:
        type: integer
      maxValue:
        type: integer
      maxVoteOverwrites:
        type: integer
      uniqueChoices:
        type: boolean
    type: object
  db.VotingTypes:
    properties:
      approval:
        type: boolean
      cumulative:
        type: boolean
      multiple:
        type: boolean
      ranked:
        type: boolean
      single:
        type: boolean
      weighted:
        type: boolean
    type: object
  errors.Error:
    properties:
      code:
        description: Error code
        type: integer
      data:
        description: Optional data to include in the error response
      error:
        description: Original error
      httpstatus:
        description: HTTP status code to return
        type: integer
      logLevel:
        description: Log level for this error (defaults to "debug")
        type: string
    type: object
  github_com_vocdoni_saas-backend_stripe.CheckoutSessionStatus:
    properties:
      customer_email:
        type: string
      status:
        type: string
      subscription_status:
        type: string
    type: object
  handlers.AuthRequest:
    properties:
      birthDate:
        type: string
      email:
        type: string
      memberNumber:
        type: string
      name:
        type: string
      nationalId:
        type: string
      phone:
        type: string
      surname:
        type: string
    type: object
  handlers.AuthResendRequest:
    properties:
      authToken:
        example: deadbeef
        format: hex
        type: string
      email:
        type: string
      phone:
        type: string
    type: object
  handlers.AuthResponse:
    properties:
      authToken:
        example: deadbeef
        format: hex
        type: string
      signature:
        example: deadbeef
        format: hex
        type: string
      weight:
        example: 2a
        format: hex
        type: string
    type: object
  handlers.CheckMembershipRequest:
    properties:
      authToken:
        example: deadbeef
        format: hex
        type: string
      electionId:
        example: deadbeef
        format: hex
        type: string
    type: object
  handlers.CheckMembershipResponse:
    properties:
      belongs:
        type: boolean
      hasVoted:
        type: boolean
      weight:
        example: 2a
        format: hex
        type: string
    type: object
  handlers.ConsumedAddressRequest:
    properties:
      authToken:
        example: deadbeef
        format: hex
        type: string
    type: object
  handlers.ConsumedAddressResponse:
    properties:
      address:
        example: deadbeef
        format: hex
        type: string
      at:
        type: string
      nullifier:
        example: deadbeef
        format: hex
        type: string
    type: object
  handlers.SignRequest:
    properties:
      authToken:
        example: deadbeef
        format: hex
        type: string
      electionId:
        example: deadbeef
        format: hex
        type: string
      payload:
        type: string
      tokenR:
        example: deadbeef
        format: hex
        type: string
    type: object
  handlers.UserWeightRequest:
    properties:
      authToken:
        example: deadbeef
        format: hex
        type: string
    type: object
  handlers.UserWeightResponse:
    properties:
      weight:
        example: 2a
        format: hex
        type: string
    type: object
host: localhost:8080
info:
  contact:
    email: info@vocdoni.io
    name: API Support
    url: https://vocdoni.io
  description: API for Vocdoni SaaS Backend
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
  termsOfService: http://swagger.io/terms/
  title: Vocdoni SaaS API
  version: "1.0"
paths:
  /auth/addresses:
    get:
      consumes:
      - application/json
      description: Get the list of organization addresses the user belongs to
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationAddresses'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: No organizations found
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get a list of addresses the user belongs to
      tags:
      - auth
  /auth/login:
    post:
      consumes:
      - application/json
      description: Authenticate a user and get a JWT token
      parameters:
      - description: Login credentials
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.UserInfo'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.LoginResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Login to get a JWT token
      tags:
      - auth
  /auth/oauth/{provider}:
    delete:
      consumes:
      - application/json
      description: Unlink an OAuth provider from an authenticated account. Cannot
        unlink the last authentication method.
      parameters:
      - description: OAuth provider name (google, github, facebook)
        in: path
        name: provider
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid provider, provider not linked, or cannot unlink last
            auth method
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Unlink OAuth provider from account
      tags:
      - auth
  /auth/oauth/link:
    post:
      consumes:
      - application/json
      description: Link an OAuth provider to an existing authenticated account
      parameters:
      - description: OAuth link information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.OAuthLinkRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid provider or provider already linked
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized or signature verification failed
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Link OAuth provider to account
      tags:
      - auth
  /auth/refresh:
    post:
      consumes:
      - application/json
      description: Refresh the JWT token for an authenticated user
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.LoginResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Refresh JWT token
      tags:
      - auth
  /census:
    post:
      consumes:
      - application/json
      description: |-
        Create a new census for an organization. Requires Manager/Admin role. Members are
        added later (see POST /census/{id}); this only creates the empty census.

        Also callable with a scoped API key (scope: `voting:write`).
      parameters:
      - description: Census information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.CreateCensusRequest'
      produces:
      - application/json
      responses:
        "200":
          description: Returns the created census ID
          schema:
            $ref: '#/definitions/apicommon.CreateCensusResponse'
        "400":
          description: Invalid input data or missing required fields
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Create a new census
      tags:
      - census
  /census/{id}:
    get:
      consumes:
      - application/json
      description: Retrieve census information by ID. Returns census type, organization
        address, and creation time.
      parameters:
      - description: Census ID
        in: path
        name: id
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationCensus'
        "400":
          description: Invalid census ID
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Census not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Get census information
      tags:
      - census
    post:
      consumes:
      - application/json
      description: |-
        Add existing organization members to a census by member ID (synchronous). Members
        already in the census are skipped. Returns the number of participants added plus
        per-member errors in the response `errors` field. An empty member ID list is a no-op
        that returns added=0. Requires Manager/Admin role and is subject to the plan's census
        quota.

        Also callable with a scoped API key (scope: `voting:write`).
      parameters:
      - description: Census ID
        in: path
        name: id
        required: true
        type: string
      - description: Participant member IDs to add
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.AddCensusParticipantsRequest'
      produces:
      - application/json
      responses:
        "200":
          description: Added count and optional per-member errors
          schema:
            $ref: '#/definitions/apicommon.AddMembersResponse'
        "400":
          description: Invalid input data or census not found
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Plan census quota exceeded
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Census not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Add organization members to a census
      tags:
      - census
  /census/{id}/group/{groupid}/publish:
    post:
      consumes:
      - application/json
      description: |-
        Publish a census based on a specific organization members group for voting. Requires Manager/Admin role.
        The request body selects the CSP authentication: at least one of authFields or twoFaFields
        must be provided. Supplying only authFields yields an auth-only census (members authenticate
        with their data, no OTP); twoFaFields adds an email/SMS OTP challenge. A body with both empty
        is rejected with 404 (ErrCensusTypeNotFound). Subject to the plan's census quota. Idempotent:
        an already-published census is returned as-is. Returns the published census root and URI.

        Also callable with a scoped API key (scope: `voting:write`).
      parameters:
      - description: Census ID
        in: path
        name: id
        required: true
        type: string
      - description: Group ID
        in: path
        name: groupid
        required: true
        type: string
      - description: Census authentication configuration
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.PublishCensusGroupRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.PublishedCensusResponse'
        "400":
          description: Invalid census ID or group ID
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Plan census quota exceeded
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Census not found, or neither authFields nor twoFaFields provided
            (ErrCensusTypeNotFound)
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Publish a group-based census for voting
      tags:
      - census
  /census/{id}/participants:
    get:
      consumes:
      - application/json
      description: Retrieve participants of a census by ID. Requires Manager/Admin
        role.
      parameters:
      - description: Census ID
        in: path
        name: id
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.CensusParticipantsResponse'
        "400":
          description: Invalid census ID
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Census not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get census participants
      tags:
      - census
  /census/{id}/publish:
    post:
      consumes:
      - application/json
      description: |-
        Publish a census for voting (the CSP public key becomes the census root). Requires
        Manager/Admin role. Returns the published census URI and root. Idempotent: a census
        that is already published is returned as-is without re-publishing.

        Also callable with a scoped API key (scope: `voting:write`).
      parameters:
      - description: Census ID
        in: path
        name: id
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.PublishedCensusResponse'
        "400":
          description: Invalid census ID
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Census not found or unsupported census type
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Publish a census for voting
      tags:
      - census
  /info:
    get:
      description: Returns the service version, build information and the Vocdoni
        chain ID.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/api.InfoResponse'
      summary: Get service information
      tags:
      - health
  /integrator:
    get:
      description: |-
        Returns whether the caller's organization (resolved from the API key's org or the user
        session — no address in the URL) is enabled as an integrator, along with its effective
        managed-resource limits and current usage. The caller must be an admin or manager of the
        organization. When the organization is not an integrator, `enabled` is false and `limits`
        is omitted (usage counters are still returned). A 0 in any limit field means unlimited.

        Also callable with a scoped API key (scope: `quota:read`).
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.IntegratorInfoResponse'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get integrator quota and usage
      tags:
      - organizations
  /integrator/organizations:
    get:
      description: |-
        Returns a paginated list of organizations managed by the caller's integrator
        organization (resolved from the API key's org or the user session — no address in the
        URL). The caller must be an admin or manager of the integrator organization.

        Also callable with a scoped API key (scope: `managed:read`).
      parameters:
      - description: 'Page number (default: 1)'
        in: query
        name: page
        type: integer
      - description: 'Number of items per page (default: 10)'
        in: query
        name: limit
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.ListManagedOrganizations'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: List organizations managed by an integrator
      tags:
      - organizations
    post:
      consumes:
      - application/json
      description: |-
        Create a new organization managed by the caller's integrator organization. The
        integrator is resolved from the authenticated principal (the API key's org, or the
        user's organization for a session) — no address is passed in the URL. The caller must
        be an admin of that integrator organization, which must be enabled as an integrator and
        within its managed-organizations quota. The managed org's on-chain account is always
        provisioned eagerly. The optional `ownerEmail` designates the managed org's owner/admin
        (defaults to the calling user); the per-user MaxOrgsPerUser cap is bypassed for managed orgs.

        Also callable with a scoped API key (scope: `managed:write`).
      parameters:
      - description: Managed organization information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.CreateManagedOrganizationRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationInfo'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Not an integrator or quota reached
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Integrator organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Create a managed organization under an integrator
      tags:
      - organizations
  /integrator/organizations/{orgAddress}:
    delete:
      description: |-
        Delete the managed organization at {orgAddress} together with every piece of data
        tied to it (memberbase, censuses + participants, processes, bundles, CSP tokens,
        jobs, pending invites), and unlink it from its members. The caller must be an admin
        of their integrator organization (resolved from the API key's org or the user session
        — no address in the URL), and the target must be managed by it. The integrator's usage
        counters are rolled back accordingly.

        Deletion is blocked with 409 when any of the managed org's published elections is
        still active on-chain (READY/PAUSED); end them (or wait for them to end) first.
        The on-chain organization account and any published elections/censuses are immutable
        on the Vochain and are not affected — only DB-side data is removed.

        Also callable with a scoped API key (scope: `managed:write`).
      parameters:
      - description: Managed organization address to delete
        in: path
        name: orgAddress
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.DeleteManagedOrganizationResponse'
        "400":
          description: Invalid address
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Managed organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "409":
          description: Managed organization has active elections
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Delete a managed organization and all its data
      tags:
      - organizations
  /jobs/{jobId}:
    get:
      description: |-
        Returns the current state of a transaction job created by an async endpoint
        (publish, status change or vote relay). Always responds 200; the `status` field
        carries the lifecycle state (`pending`, `completed` or `failed`). On `completed`
        the `result` field holds the public on-chain outcome; on `failed` the `error`
        field holds the reason. Public endpoint: the 32-byte job id is the capability and
        results contain only public on-chain data.
      parameters:
      - description: Job id returned by the async endpoint (hex)
        in: path
        name: jobId
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: Job status and (when completed) result
          schema:
            $ref: '#/definitions/apicommon.JobStatusResponse'
        "400":
          description: Invalid job id
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Job not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Poll the status of an async transaction job
      tags:
      - process
  /oauth/login:
    post:
      consumes:
      - application/json
      description: Register or authenticate a user (OAuth or email/password) and return
        a JWT token
      parameters:
      - description: Login credentials; see description for details
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.OAuthLoginRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OAuthLoginResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Login using OAuth service or classic credentials
      tags:
      - auth
  /organizations:
    post:
      consumes:
      - application/json
      description: |-
        Create a new organization. If the organization is a suborganization, the parent organization must be
        specified in the request body, and the user must be an admin of the parent. If the parent organization
        is already a suborganization, an error is returned.

        Two optional opt-in fields support the chain-abstracted flow (both default false, preserving the legacy
        behavior): `provisionAccount` forges the organization's on-chain account eagerly at creation time
        (idempotent) instead of leaving it to the legacy SDK createAccount path; `integrator` subscribes the
        new organization to the free integrator plan so it becomes an integrator on the free tier with no
        checkout.
      parameters:
      - description: Organization info (+ optional provisionAccount / integrator)
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.CreateOrganizationRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationInfo'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Parent org not found, or free integrator plan unavailable (integrator=true)
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Create a new organization
      tags:
      - organizations
  /organizations/{address}:
    get:
      consumes:
      - application/json
      description: Get information about an organization
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationInfo'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Get organization information
      tags:
      - organizations
    put:
      consumes:
      - application/json
      description: |-
        Update the information of an organization.
        Only the admin of the organization can update the information.
        Only certain fields can be updated, and they will be updated only if they are not empty.
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Organization information to update
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.OrganizationInfo'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Update organization information
      tags:
      - organizations
  /organizations/{address}/apikeys:
    get:
      description: |-
        Returns the metadata of all API keys owned by the organization (never the secret).
        The caller must be an admin of the organization.
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.ListAPIKeysResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: List an organization's API keys
      tags:
      - apikeys
    post:
      consumes:
      - application/json
      description: |-
        Create a new API key owned by the organization at the given address. The caller
        must be an admin of the organization, which must be enabled as an integrator —
        API keys are integrator-only. The plaintext secret (prefixed "vsk_") is
        returned ONCE in the response and cannot be retrieved again.

        `label` and at least one `scope` are required. Valid scopes are deny-by-default and
        must be a subset of: `quota:read`, `managed:read`, `managed:write`, `voting:write`,
        `members:write`. The optional `expiresAt`, when set, must be in the future.
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: API key information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.CreateAPIKeyRequest'
      produces:
      - application/json
      responses:
        "200":
          description: Created key including the one-time plaintext secret
          schema:
            $ref: '#/definitions/apicommon.CreateAPIKeyResponse'
        "400":
          description: Invalid input (bad address, missing label/scopes, unknown scope,
            past expiresAt)
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Organization is not an integrator
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Create an API key for an organization
      tags:
      - apikeys
  /organizations/{address}/apikeys/{keyID}:
    delete:
      description: |-
        Revokes (permanently disables) the API key with the given ID. The caller must be
        an admin of the organization.
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: API key ID
        in: path
        name: keyID
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data (missing key ID)
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: API key not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Revoke an organization's API key
      tags:
      - apikeys
  /organizations/{address}/censuses:
    get:
      consumes:
      - application/json
      description: Get the list of censuses for an organization
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationCensuses'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get organization censuses
      tags:
      - organizations
  /organizations/{address}/groups:
    get:
      consumes:
      - application/json
      description: |-
        Get the list of groups and their info of the organization
        Does not return the members of the groups, only the groups themselves.
        Needs admin or manager role.

        Also callable with a scoped API key (scope: `members:write`).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: 'Page number (default: 1)'
        in: query
        name: page
        type: integer
      - description: 'Number of items per page (default: 10)'
        in: query
        name: limit
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationMemberGroupsResponse'
        "400":
          description: Invalid input data, or organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get organization member groups
      tags:
      - organizations
    post:
      consumes:
      - application/json
      description: |-
        Create an organization member group with the given members, or with all members when
        `includeAllMembers` is set. Needs admin or manager role.

        Also callable with a scoped API key (scope: `members:write`).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Group info to create
        in: body
        name: group
        required: true
        schema:
          $ref: '#/definitions/apicommon.CreateOrganizationMemberGroupRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationMemberGroupInfo'
        "400":
          description: Invalid input data, or organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Create an organization member group
      tags:
      - organizations
  /organizations/{address}/groups/{groupID}:
    delete:
      consumes:
      - application/json
      description: |-
        Delete an organization member group by its ID. Needs admin or manager role. The
        auto-generated "All members" group cannot be deleted.

        Also callable with a scoped API key (scope: `members:write`).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Group ID
        in: path
        name: groupID
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data, or organization/group not found
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Auto-generated group cannot be deleted
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Delete an organization member group
      tags:
      - organizations
    get:
      consumes:
      - application/json
      description: |-
        Get the information of an organization member group by its ID
        Needs admin or manager role.

        Also callable with a scoped API key (scope: `members:write`).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Group ID
        in: path
        name: groupID
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationMemberGroupInfo'
        "400":
          description: Invalid input data, or organization/group not found
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get the information of an organization member group
      tags:
      - organizations
    put:
      consumes:
      - application/json
      description: |-
        Update an organization member group changing the info, and adding or removing members.
        Needs admin or manager role. The auto-generated "All members" group cannot have its
        membership modified.

        Also callable with a scoped API key (scope: `members:write`).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Group ID
        in: path
        name: groupID
        required: true
        type: string
      - description: Group info to update
        in: body
        name: group
        required: true
        schema:
          $ref: '#/definitions/apicommon.UpdateOrganizationMemberGroupsRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data, or organization/group not found
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Auto-generated group membership cannot be modified
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Update an organization member group
      tags:
      - organizations
  /organizations/{address}/groups/{groupID}/members:
    get:
      consumes:
      - application/json
      description: |-
        Get the paginated list of members with details of an organization member group.
        Needs admin or manager role.

        Also callable with a scoped API key (scope: `members:write`).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Group ID
        in: path
        name: groupID
        required: true
        type: string
      - description: Page number for pagination
        in: query
        name: page
        type: integer
      - description: Number of items per page
        in: query
        name: limit
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.ListOrganizationMemberGroupResponse'
        "400":
          description: Invalid input data, or organization/group not found
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get the list of members with details of an organization member group
      tags:
      - organizations
  /organizations/{address}/groups/{groupID}/validate:
    post:
      consumes:
      - application/json
      description: |-
        Checks the AuthFields for duplicates or empty fields and the TwoFaFields for empty ones.
        On failure the offending member IDs are returned in the error `data`. Needs admin or
        manager role.

        Also callable with a scoped API key (scope: `members:write`).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Group ID
        in: path
        name: groupID
        required: true
        type: string
      - description: Members validation request
        in: body
        name: members
        required: true
        schema:
          $ref: '#/definitions/apicommon.ValidateMemberGroupRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data, duplicate/missing fields, or organization/group
            not found
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Validate organization group members data
      tags:
      - organizations
  /organizations/{address}/jobs:
    get:
      consumes:
      - application/json
      description: Get the list of import jobs for an organization with pagination
        support
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: 'Page number (default: 1)'
        in: query
        name: page
        type: integer
      - description: 'Number of items per page (default: 10)'
        in: query
        name: limit
        type: integer
      - description: Filter by job type (org_members or census_participants)
        in: query
        name: type
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.JobsResponse'
        "400":
          description: Invalid input
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get organization jobs
      tags:
      - organizations
  /organizations/{address}/members:
    delete:
      consumes:
      - application/json
      description: |-
        Delete specific members (by ID) or all members of an organization. Requires Manager/Admin
        role. An empty ID list (without the `all` flag) is a no-op that returns count=0.

        Also callable with a scoped API key (scope: `members:write`).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Member IDs to delete or all flag
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.DeleteMembersRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.DeleteMembersResponse'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Delete organization members
      tags:
      - organizations
    get:
      consumes:
      - application/json
      description: |-
        Retrieve all members of an organization with pagination support. Requires Manager/Admin role.

        Also callable with a scoped API key (scope: `members:write`).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: 'Page number (default: 1)'
        in: query
        name: page
        type: integer
      - description: 'Number of items per page (default: 10)'
        in: query
        name: limit
        type: integer
      - description: Search term for member properties
        in: query
        name: search
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationMembersResponse'
        "400":
          description: Invalid input
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get organization members
      tags:
      - organizations
    post:
      consumes:
      - application/json
      description: |-
        Add multiple members to an organization. Requires Manager/Admin role and is subject to the
        plan's member quota. With `async=true` the import runs in the background and the response
        carries a `jobId` to poll via GET /organizations/{address}/members/job/{jobid}; otherwise it
        completes synchronously. An empty members list is a no-op that returns added=0.

        Also callable with a scoped API key (scope: `members:write`).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Process asynchronously and return job ID
        in: query
        name: async
        type: boolean
      - description: Members to add
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.AddMembersRequest'
      produces:
      - application/json
      responses:
        "200":
          description: Added count (sync) or jobId (async)
          schema:
            $ref: '#/definitions/apicommon.AddMembersResponse'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Plan member quota exceeded
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Add members to an organization
      tags:
      - organizations
    put:
      consumes:
      - application/json
      description: |-
        Create or update an organization member. Requires Manager/Admin role.
        Automatically updates census participant hashes when member data changes.

        Also callable with a scoped API key (scope: `members:write`).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Member data to insert or update
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.OrgMember'
      produces:
      - application/json
      responses:
        "200":
          description: ID of member inserted or updated
          schema:
            $ref: '#/definitions/apicommon.OrgMember'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Create or update an organization member
      tags:
      - organizations
  /organizations/{address}/members/job/{jobid}:
    get:
      consumes:
      - application/json
      description: |-
        Check the progress of a job to add members to an organization. Returns the progress of the job.
        While a job is running its status is served from memory; once completed, the in-memory status
        is evicted after 60 seconds. Completed jobs remain retrievable afterwards from the persisted
        job record (returned with progress 100).

        Also callable with a scoped API key (scope: `members:write`).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Job ID
        in: path
        name: jobid
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.AddMembersJobResponse'
        "400":
          description: Invalid job ID
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Job not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Check the progress of adding members
      tags:
      - organizations
  /organizations/{address}/processes:
    get:
      consumes:
      - application/json
      description: |-
        Returns a paginated list of process bundles for an organization.
        Each entry contains the bundle ID, the primary vochain process ID
        (first element of Processes when present), and all process IDs in the bundle.
        Requires the user to be part of the organization (any role).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Page number (default 1)
        in: query
        name: page
        type: integer
      - description: Items per page (default 10, max 100)
        in: query
        name: limit
        type: integer
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.ListOrganizationBundles'
        "400":
          description: Invalid request or organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: List organization bundles and their main process
      tags:
      - process
  /organizations/{address}/processes/drafts:
    get:
      consumes:
      - application/json
      description: Returns a list of voting process drafts.
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.ListOrganizationProcesses'
        "404":
          description: Process not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Get paginated list of process drafts
      tags:
      - process
  /organizations/{address}/subscription:
    get:
      consumes:
      - application/json
      description: Get the subscription information for an organization
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationSubscriptionInfo'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found or no subscription
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get organization subscription
      tags:
      - organizations
  /organizations/{address}/ticket:
    post:
      consumes:
      - application/json
      description: Create a new ticket for an organization. The user must have some
        role in the organization (any role).
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Ticket request information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.CreateOrganizationTicketRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Create a new ticket for an organization
      tags:
      - organizations
  /organizations/{address}/users:
    get:
      consumes:
      - application/json
      description: Get the list of users with their roles in the organization
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationUsers'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get organization users
      tags:
      - organizations
    post:
      consumes:
      - application/json
      description: |-
        Invite a new user to an organization. Only the admin of the organization can invite a new user.
        It stores the invitation in the database and sends an email to the new user with the invitation code.
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Invitation information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.OrganizationInvite'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "409":
          description: User already has a role in the organization
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Invite a new user to an organization
      tags:
      - organizations
  /organizations/{address}/users/{userid}:
    delete:
      consumes:
      - application/json
      description: Remove a user from the organization. Only the admin of the organization
        can remove a user.
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: User ID
        in: path
        name: userid
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data - User cannot remove itself
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Remove a user from the organization
      tags:
      - organizations
    put:
      consumes:
      - application/json
      description: Update the role of a user in an organization. Only the admin of
        the organization can update the role.
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: User ID
        in: path
        name: userid
        required: true
        type: string
      - description: Update user role information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.UpdateOrganizationUserRoleRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Update organization user role
      tags:
      - organizations
  /organizations/{address}/users/accept:
    post:
      consumes:
      - application/json
      description: |-
        Accept an invitation to an organization. It checks if the invitation is valid and not expired, and that the
        user has no role in the organization yet. If the user does not exist, it creates a new user with the provided
        information. If the user already exists and is verified, it assigns a role to the user in the organization.
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Invitation acceptance information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.AcceptOrganizationInvitation'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized or invalid invitation
          schema:
            $ref: '#/definitions/errors.Error'
        "409":
          description: User already has a role in the organization
          schema:
            $ref: '#/definitions/errors.Error'
        "410":
          description: Invitation expired
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Accept an invitation to an organization
      tags:
      - organizations
  /organizations/{address}/users/pending:
    get:
      consumes:
      - application/json
      description: Get the list of pending invitations for an organization
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationInviteList'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get pending organization users
      tags:
      - organizations
  /organizations/{address}/users/pending/{invitationID}:
    delete:
      consumes:
      - application/json
      description: |-
        Delete a pending invitation to an organization by email.
        Only the admin of the organization can delete an invitation.
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Invitation ID
        in: path
        name: invitationID
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid data - invitation not found
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Delete a pending invitation to an organization
      tags:
      - organizations
    put:
      consumes:
      - application/json
      description: |-
        Update the code, link and expiration time of a pending invitation to an organization by email.
        Resend the invitation email.
        Only the admin of the organization can update an invitation.
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      - description: Invitation ID
        in: path
        name: invitationID
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid data - invitation not found
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Update a pending invitation to an organization
      tags:
      - organizations
  /organizations/{orgAddress}/meta:
    delete:
      consumes:
      - application/json
      description: Deletes a set of keys from the meta information of an organization.
      parameters:
      - description: Organization address
        in: path
        name: orgAddress
        required: true
        type: string
      - description: Keys to delete from the organization meta
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.OrganizationDeleteMetaRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Forbidden - User is not a manager or admin of the organization
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "422":
          description: Invalid meta information
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Delete organization meta information
      tags:
      - organizations
    get:
      consumes:
      - application/json
      description: Retrieves the meta information of an organization. Requires Manager/Admin
        role.
      parameters:
      - description: Organization address
        in: path
        name: orgAddress
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: Organization meta information
          schema:
            $ref: '#/definitions/apicommon.OrganizationMetaResponse'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Forbidden - User is not a manager or admin of the organization
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get organization meta information
      tags:
      - organizations
    post:
      consumes:
      - application/json
      description: Overwrite the meta information of an organization. Requires Manager/Admin
        role.
      parameters:
      - description: Organization address
        in: path
        name: orgAddress
        required: true
        type: string
      - description: Meta information to add to the organization
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.OrganizationAddMetaRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Forbidden - User is not a manager or admin of the organization
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "422":
          description: Invalid meta information
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Add meta information to an organization
      tags:
      - organizations
    put:
      consumes:
      - application/json
      description: |-
        Updates existing or adds new key/value pairs in the meta information of an organization.
        Has only one layer of depth. If a second layer document is provided, for example meta.doc = [a,b,c],
        the entire document will be updated.
        Requires Manager/Admin role.
      parameters:
      - description: Organization address
        in: path
        name: orgAddress
        required: true
        type: string
      - description: Meta information to update in the organization
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.OrganizationAddMetaRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Forbidden - User is not a manager or admin of the organization
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "422":
          description: Invalid meta information
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Update organization meta information
      tags:
      - organizations
  /organizations/roles:
    get:
      consumes:
      - application/json
      description: Get the list of available roles that can be assigned to a user
        of an organization
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationRoleList'
      summary: Get available organization user roles
      tags:
      - organizations
  /organizations/types:
    get:
      consumes:
      - application/json
      description: Get the list of available organization types that can be assigned
        to an organization
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.OrganizationTypeList'
      summary: Get available organization types
      tags:
      - organizations
  /plans:
    get:
      consumes:
      - application/json
      description: Get the list of publicly available subscription plans
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            items:
              $ref: '#/definitions/db.Plan'
            type: array
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Get all subscription plans
      tags:
      - plans
  /process:
    post:
      consumes:
      - application/json
      description: |-
        Create a new voting process (draft). Requires Manager/Admin role of the owning organization. The
        request must reference the organization via either a `censusId` or an explicit `orgAddress`.
        Creating a draft consumes the plan's draft permission.

        The optional `electionParams` field carries the on-chain election definition (questions, dates,
        vote/election types) used later to publish the draft on chain via POST /process/{processId}/publish.
        It is additive: omitting it keeps the legacy draft behavior.

        Also callable with a scoped API key (scope: `voting:write`).
      parameters:
      - description: Process creation information (optionally with electionParams)
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.CreateProcessRequest'
      produces:
      - application/json
      responses:
        "200":
          description: 'Bare JSON string: 24-hex draft ProcessID, e.g. 507f1f77bcf86cd799439011'
          schema:
            type: string
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Plan does not allow creating more drafts
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Published census not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Create a new voting process
      tags:
      - process
  /process/{processId}:
    delete:
      consumes:
      - application/json
      description: |-
        Delete a draft voting process. Only unpublished drafts can be deleted; a process
        already published on-chain cannot be removed. Requires Manager/Admin role of the
        organization that owns the process.

        Also callable with a scoped API key (scope: `voting:write`).
      parameters:
      - description: Process ID
        in: path
        name: processId
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid process ID
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Process not found
          schema:
            $ref: '#/definitions/errors.Error'
        "409":
          description: Process already published and not in draft mode
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Delete a draft voting process
      tags:
      - process
    get:
      consumes:
      - application/json
      description: |-
        Retrieve voting process information by ID. Returns process details including census and metadata.
        For encrypted (secretUntilTheEnd) elections the response additionally carries the election's
        encryption public keys in `encryptionKeys` (one per keykeeper) once they are published on chain;
        the field is absent for non-encrypted elections and before the keys are published.
      parameters:
      - description: Process ID
        in: path
        name: processId
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.ProcessInfo'
        "400":
          description: Invalid process ID
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Process not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Get process information
      tags:
      - process
    put:
      consumes:
      - application/json
      description: |-
        Update an existing draft voting process. Requires Manager/Admin role of the owning organization.
        Only drafts that have not yet been published on chain can be updated; updating a published process
        returns a 409. The optional `electionParams` field can be set or replaced here (additive), same as on
        create.
      parameters:
      - description: 24-hex draft ProcessID
        in: path
        name: processId
        required: true
        type: string
      - description: Process update information (optionally with electionParams)
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.UpdateProcessRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Process not found
          schema:
            $ref: '#/definitions/errors.Error'
        "409":
          description: Process already published and not in draft mode
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Update an existing voting process
      tags:
      - process
  /process/{processId}/metadata:
    get:
      description: |-
        Rebuilds and returns the raw ElectionMetadata JSON document of the process
        identified by its process id. The metadata is deterministically derived
        from the stored ElectionParams, so it is identical to the content-addressed document
        published on chain. Public endpoint: no authentication is required.
      parameters:
      - description: 24-hex ProcessID
        in: path
        name: processId
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: Election metadata JSON
          schema:
            type: object
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Process not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Get the election metadata JSON
      tags:
      - process
  /process/{processId}/publish:
    post:
      consumes:
      - application/json
      description: |-
        Publishes an existing draft process (created via POST /process) as an on-chain
        election. The backend builds the election metadata and NewProcess transaction,
        funds and signs it (with the organization signer) synchronously, then submits and
        confirms it on a background worker; the call returns 202 with a job id. Poll GET
        /jobs/{jobId} for the resulting on-chain id. Requires Admin role. Idempotent: if
        the draft is already published its on-chain id is returned with 200 without sending
        a new transaction. Publishing under a managed organization additionally enforces the
        integrator's aggregate election (process-count) quota.

        Also callable with a scoped API key (scope: `voting:write`).
      parameters:
      - description: Draft process ID
        in: path
        name: processId
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: 'Already published (idempotent): on-chain id and status'
          schema:
            $ref: '#/definitions/apicommon.PublishProcessResponse'
        "202":
          description: Publish accepted; poll GET /jobs/{jobId}
          schema:
            $ref: '#/definitions/apicommon.EnqueuedResponse'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Process not found
          schema:
            $ref: '#/definitions/errors.Error'
        "409":
          description: A publish is already in progress for this draft
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
        "503":
          description: Transaction queue is full
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Publish a draft process as an on-chain election
      tags:
      - process
  /process/{processId}/results:
    get:
      description: |-
        Fetches the current on-chain state of the election identified by its process id
        and returns a trimmed view of it: status, vote count, start/end dates, whether the
        results are final and the tally (if any). Public endpoint: no authentication is
        required.
      parameters:
      - description: 24-hex ProcessID
        in: path
        name: processId
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: Trimmed on-chain election state
          schema:
            $ref: '#/definitions/apicommon.ProcessResultsResponse'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Process not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Get the trimmed on-chain election results
      tags:
      - process
  /process/{processId}/sign-info:
    post:
      consumes:
      - application/json
      description: |-
        Get the address used to sign a process. Requires a verified token. Returns the address, nullifier,
        and timestamp of the consumption. {processId} accepts the 24-hex ProcessID (preferred)
        or, for backwards compatibility, the 64-hex on-chain election id.
      parameters:
      - description: 24-hex ProcessID (preferred); 64-hex on-chain id also accepted
        in: path
        name: processId
        required: true
        type: string
      - description: Request with auth token
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/handlers.ConsumedAddressRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.ConsumedAddressResponse'
        "400":
          description: Invalid input data or user has not voted (ErrUserNoVoted)
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized, invalid token, or token not verified (ErrAuthTokenNotVerified)
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Process not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Get the address used to sign a process
      tags:
      - csp
  /process/{processId}/status:
    put:
      consumes:
      - application/json
      description: |-
        Changes the status of an on-chain election (ready|paused|ended|canceled). The
        backend builds a SET_PROCESS_STATUS transaction, funds and signs it with the
        organization signer synchronously, then submits and confirms it on a background
        worker; the call returns 202 with a job id. Poll GET /jobs/{jobId} for the result.
        Requires Manager/Admin role of the organization that owns the process.

        Also callable with a scoped API key (scope: `voting:write`).
      parameters:
      - description: 24-hex ProcessID
        in: path
        name: processId
        required: true
        type: string
      - description: New process status
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.SetProcessStatusRequest'
      produces:
      - application/json
      responses:
        "202":
          description: Job accepted; poll GET /jobs/{jobId}
          schema:
            $ref: '#/definitions/apicommon.EnqueuedResponse'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Process not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
        "503":
          description: Transaction queue is full
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Change an on-chain election status
      tags:
      - process
  /process/bundle:
    post:
      consumes:
      - application/json
      description: |-
        Create a new process bundle linking a census to an optional list of on-chain processes,
        used by the CSP voter flow. Requires Manager/Admin role for the organization that owns
        the census. The census root is the CSP (account) public key.

        Also callable with a scoped API key (scope: `voting:write`).
      parameters:
      - description: Process bundle creation information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.CreateProcessBundleRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.CreateProcessBundleResponse'
        "400":
          description: Invalid input data, or census/organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Create a new process bundle
      tags:
      - process
  /process/bundle/{bundleId}:
    get:
      consumes:
      - application/json
      description: |-
        Retrieve process bundle information by ID. Returns bundle details including the associated census,
        census root, organization address, and list of processes.
      parameters:
      - description: Bundle ID
        in: path
        name: bundleId
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.ProcessBundleInfo'
        "400":
          description: Invalid bundle ID
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Bundle not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Get process bundle information
      tags:
      - process
    put:
      consumes:
      - application/json
      description: |-
        Add additional on-chain processes to an existing bundle. Requires Manager/Admin role for
        the organization that owns the bundle. An empty process list is a no-op that returns the
        bundle's current root.

        Also callable with a scoped API key (scope: `voting:write`).
      parameters:
      - description: Bundle ID
        in: path
        name: bundleId
        required: true
        type: string
      - description: Processes to add
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/api.AddProcessesToBundleRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.CreateProcessBundleResponse'
        "400":
          description: Invalid input data, or bundle not found
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Add processes to an existing bundle
      tags:
      - process
  /process/bundle/{bundleId}/{participantId}:
    get:
      consumes:
      - application/json
      description: |-
        Retrieve process information for a participant in a process bundle. Returns process details including
        the census and metadata.
      parameters:
      - description: Bundle ID
        in: path
        name: bundleId
        required: true
        type: string
      - description: Participant ID
        in: path
        name: participantID
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema: {}
        "400":
          description: Invalid bundle ID or participant ID
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Bundle not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Get participant information for a process bundle
      tags:
      - process
  /process/bundle/{bundleId}/auth/{step}:
    post:
      consumes:
      - application/json
      description: |-
        Handle authentication for a process bundle. There are two steps in the authentication process:
        - Step 0: The user sends the participant ID and contact information (email or phone).
        If valid, the server sends a challenge to the user with a token.
        - Step 1: The user sends the token and challenge solution back to the server.
        If valid, the token is marked as verified and returned.
        For auth-only censuses, verification may not require a challenge solution.

        The request body depends on the step:
        - Step 0: handlers.AuthRequest — member identification fields (name, surname, memberNumber,
        nationalId, birthDate, email, phone); which are required depends on the census auth configuration.
        - Step 1: handlers.AuthChallengeRequest — { authToken, authData: [challenge solution] }.
      parameters:
      - description: Bundle ID
        in: path
        name: bundleId
        required: true
        type: string
      - description: Authentication step (0 or 1)
        in: path
        name: step
        required: true
        type: string
      - description: Step 0 body; step 1 uses AuthChallengeRequest (see description)
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/handlers.AuthRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.AuthResponse'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized, cooldown time not reached (ErrAttemptCoolDownTime),
            or invalid challenge
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: census participant not found (ErrCensusParticipantNotFound)
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Authenticate for a process bundle
      tags:
      - csp
  /process/bundle/{bundleId}/auth/resend:
    post:
      consumes:
      - application/json
      description: |-
        Resend the challenge for an existing (non-verified) authentication token.
        The request must include the auth token and a valid contact method for the bundle census type
        (email, phone, or either depending on census configuration).
        The same token is returned if the challenge is queued successfully.
      parameters:
      - description: Bundle ID
        in: path
        name: bundleId
        required: true
        type: string
      - description: Resend request with auth token and contact data
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/handlers.AuthResendRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.AuthResponse'
        "400":
          description: Malformed URL/body, missing auth token, invalid contact data,
            or token already verified
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized, invalid/expired token, token not belonging to
            bundle, or contact mismatch
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error (storage/challenge generation/notification
            failures)
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Resend authentication challenge for a process bundle
      tags:
      - csp
  /process/bundle/{bundleId}/check:
    post:
      consumes:
      - application/json
      description: |-
        Check whether the user behind a CSP auth token is an eligible participant of the bundle's census.
        The user is identified solely by the auth token (the only voter data the client stores). The token
        must be verified and issued for this same bundle, and the user must be a participant of the bundle's
        census. When electionId is provided, the response also reports whether the user already voted in that
        process. Ineligibility (unknown/unverified token, token from another bundle, not in census, zero weight
        on a weighted census) is reported as belongs=false with HTTP 200, not as an error.
      parameters:
      - description: Bundle ID
        in: path
        name: bundleId
        required: true
        type: string
      - description: Request with auth token and optional election ID
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/handlers.CheckMembershipRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.CheckMembershipResponse'
        "400":
          description: Malformed URL/body or missing auth token
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Bundle not found or census not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Check census membership for a bundle
      tags:
      - csp
  /process/bundle/{bundleId}/participants/check:
    post:
      consumes:
      - application/json
      description: |-
        Look up org members by one of the allowed identification fields
        (email, phone, memberNumber, nationalId, name, surname) and return
        The request must also include the processID
        hasVoted is true when the member has used (consumed) that process to
        cast a ballot. Requires Manager/Admin role on the bundle's organization.
      parameters:
      - description: Bundle ID
        in: path
        name: bundleId
        required: true
        type: string
      - description: Lookup request
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.CheckBundleParticipantsRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.CheckBundleParticipantsResponse'
        "400":
          description: Invalid input
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Bundle not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Check whether an org member belongs to a bundle's census and have voted
      tags:
      - process
  /process/bundle/{bundleId}/sign:
    post:
      consumes:
      - application/json
      description: |-
        Sign a process in a bundle. Requires a verified token. The server signs the address with the user data
        and returns the signature. Once signed, the process is marked as consumed and cannot be signed again.
        The signing process includes verifying that the participant is in the census, that the process is part of
        the bundle, and that the authentication token is valid and verified.

        Body: authToken, electionId (the process/election ID) and payload (the voter address). tokenR is unused.
      parameters:
      - description: Bundle ID
        in: path
        name: bundleId
        required: true
        type: string
      - description: Sign request (see description for fields)
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/handlers.SignRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.AuthResponse'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized, invalid/unverified token, or process not in the
            bundle
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Bundle not found or user not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Sign a process in a bundle
      tags:
      - csp
  /process/bundle/{bundleId}/weight:
    post:
      consumes:
      - application/json
      description: Get the weight of a user for a given bundle. Requires a verified
        token.
      parameters:
      - description: Bundle ID
        in: path
        name: bundleId
        required: true
        type: string
      - description: Request with auth token
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/handlers.UserWeightRequest'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/handlers.UserWeightResponse'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: token not belonging to bundle
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Bundle not found, user not found, or census not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Get user weight for a bundle
      tags:
      - csp
  /storage:
    post:
      consumes:
      - multipart/form-data
      description: |-
        Upload images through a multipart form. Expects the request to contain a "file" field with one or more
        files to be uploaded.
      parameters:
      - description: Image file(s) to upload
        in: formData
        name: file
        required: true
        type: file
      produces:
      - application/json
      responses:
        "200":
          description: URLs of uploaded images
          schema:
            additionalProperties:
              items:
                type: string
              type: array
            type: object
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Upload images
      tags:
      - storage
  /storage/{objectName}:
    get:
      description: |-
        Download a stored object (image or JSON) inline. Retrieves the object from storage and
        serves it with its stored content type.
      parameters:
      - description: Object name
        in: path
        name: objectName
        required: true
        type: string
      produces:
      - image/jpeg
      - image/png
      - application/json
      responses:
        "200":
          description: Object contents
          schema:
            type: file
        "400":
          description: Invalid object name
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Object not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Download a stored object
      tags:
      - storage
  /subscriptions/{address}/portal:
    get:
      consumes:
      - application/json
      description: Create a Stripe customer portal session for managing subscriptions
      parameters:
      - description: Organization address
        in: path
        name: address
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: Contains portalURL
          schema:
            additionalProperties:
              type: string
            type: object
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Create a subscription portal session
      tags:
      - plans
  /subscriptions/checkout:
    post:
      consumes:
      - application/json
      description: Create a new Stripe checkout session for subscription purchases
      parameters:
      - description: Checkout information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.SubscriptionCheckout'
      produces:
      - application/json
      responses:
        "200":
          description: Contains clientSecret and sessionID
          schema:
            additionalProperties:
              type: string
            type: object
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization or plan not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Create a subscription checkout session
      tags:
      - plans
  /subscriptions/checkout/{sessionID}:
    get:
      consumes:
      - application/json
      description: Retrieve the status of a Stripe checkout session
      parameters:
      - description: Checkout session ID
        in: path
        name: sessionID
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/github_com_vocdoni_saas-backend_stripe.CheckoutSessionStatus'
        "400":
          description: Invalid session ID
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Get checkout session status
      tags:
      - plans
  /subscriptions/webhook:
    post:
      consumes:
      - application/json
      description: |-
        Process incoming webhook events from Stripe for subscription management. Handles subscription creation,
        updates, deletions, and payment events with idempotency and proper error handling.
      parameters:
      - description: Stripe webhook payload
        in: body
        name: body
        required: true
        schema:
          type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Bad Request
          schema:
            type: string
        "500":
          description: Internal Server Error
          schema:
            type: string
      summary: Handle Stripe webhook events
      tags:
      - plans
  /transactions:
    post:
      consumes:
      - application/json
      description: Sign a transaction with the organization's private key. The user
        must have a role in the organization.
      parameters:
      - description: Transaction data to sign
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.TransactionData'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.TransactionData'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Sign a transaction
      tags:
      - transactions
  /transactions/message:
    post:
      consumes:
      - application/json
      description: Sign a message with the organization's private key. The user must
        have admin role for the organization.
      parameters:
      - description: Message to sign
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.MessageSignature'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.MessageSignature'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Organization not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Sign a message
      tags:
      - transactions
  /users:
    post:
      consumes:
      - application/json
      description: Register a new user with email, password, and personal information
      parameters:
      - description: User registration information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.UserInfo'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "409":
          description: User already exists
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Register a new user
      tags:
      - users
  /users/me:
    get:
      consumes:
      - application/json
      description: Get information about the authenticated user
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.UserInfo'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Get user information
      tags:
      - users
    put:
      consumes:
      - application/json
      description: Update information for the authenticated user
      parameters:
      - description: User information to update
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.UserInfo'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.LoginResponse'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Update user information
      tags:
      - users
  /users/password:
    put:
      consumes:
      - application/json
      description: Update the password for the authenticated user
      parameters:
      - description: Password update information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.UserPasswordUpdate'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized or old password does not match
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      security:
      - BearerAuth: []
      summary: Update user password
      tags:
      - users
  /users/password/reset:
    post:
      consumes:
      - application/json
      description: Reset a user's password using a verification code
      parameters:
      - description: Password reset information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.UserPasswordReset'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized or invalid verification code
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: User not found
          schema:
            $ref: '#/definitions/errors.Error'
        "410":
          description: Verification code expired
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Reset user password
      tags:
      - users
  /users/recovery:
    post:
      consumes:
      - application/json
      description: Request a password recovery code for a user
      parameters:
      - description: User email information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.UserInfo'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Recover user password
      tags:
      - users
  /users/verify:
    post:
      consumes:
      - application/json
      description: Verify a user account with the verification code
      parameters:
      - description: Verification information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.UserVerification'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.LoginResponse'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "409":
          description: User already verified
          schema:
            $ref: '#/definitions/errors.Error'
        "410":
          description: Verification code expired
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Verify user account
      tags:
      - users
  /users/verify/code:
    get:
      consumes:
      - application/json
      description: Get information about a user's verification code
      parameters:
      - description: User email
        in: query
        name: email
        required: true
        type: string
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/apicommon.UserVerification'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: User not found
          schema:
            $ref: '#/definitions/errors.Error'
        "409":
          description: User already verified
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Get verification code information
      tags:
      - users
    post:
      consumes:
      - application/json
      description: Resend a verification code to the user's email
      parameters:
      - description: User email information
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.UserVerification'
      produces:
      - application/json
      responses:
        "200":
          description: OK
          schema:
            type: string
        "400":
          description: Invalid input data, user already verified, or max resend attempts
            reached
          schema:
            $ref: '#/definitions/errors.Error'
        "401":
          description: Unauthorized
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Resend verification code
      tags:
      - users
  /vote:
    post:
      consumes:
      - application/json
      description: |-
        Relays a voter transaction that has already been signed by the voter to the
        Vochain. The body carries a marshaled models.SignedTx whose inner Tx is a Vote
        envelope; the target process is taken from that envelope, so no process id is
        passed in the path. Public endpoint: no authentication is required. The request is
        checked synchronously — the body must decode to a Vote envelope (else 400) for a
        process the backend knows (else 404) — then enqueued for submission on a background
        worker; the call returns 202 with a job id. The chain's acceptance or rejection of
        the vote (proof, nullifier, election state) is decided when the worker submits it and
        reported on the job: poll GET /jobs/{jobId} for the voteID on success, or a failure.
      parameters:
      - description: Signed vote transaction payload
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/apicommon.RelayVoteRequest'
      produces:
      - application/json
      responses:
        "202":
          description: Job accepted; poll GET /jobs/{jobId}
          schema:
            $ref: '#/definitions/apicommon.EnqueuedResponse'
        "400":
          description: Invalid input data
          schema:
            $ref: '#/definitions/errors.Error'
        "404":
          description: Process not found
          schema:
            $ref: '#/definitions/errors.Error'
        "500":
          description: Internal server error
          schema:
            $ref: '#/definitions/errors.Error'
        "503":
          description: Transaction queue is full
          schema:
            $ref: '#/definitions/errors.Error'
      summary: Relay an already-signed vote to the Vochain
      tags:
      - process
schemes:
- http
- https
securityDefinitions:
  BearerAuth:
    description: |-
      Type "Bearer" followed by a space and either a JWT (user session) or a
      scoped API key (prefixed "vsk_"). API keys are accepted only on endpoints
      that opt into key auth, and only when the key carries the required scope.
    in: header
    name: Authorization
    type: apiKey
swagger: "2.0"
