openapi: 3.1.0
info:
  title: 1Password Accounts API for Partners
  version: v1
  description: |-
    The 1Password Accounts API for Partners lets distributors provision and manage 1Password
    product entitlements for their customers, retrieve usage data, and list the
    products available to provision.

    Resources are grouped into entitlements, usage, and products. The conventions
    for authentication, pagination, and filtering apply across the whole API.
  contact:
    name: 1Password
    url: https://1password.com/contact-us
servers:
  - url: https://api.1password.eu
    description: 1Password.eu (Europe)
tags:
  - name: Entitlements
    description: Provision, update, cancel, and link 1Password product entitlements for a customer.
  - name: Usage
    description: Retrieve product usage data for a distributor's customers.
  - name: Products
    description: List the 1Password products a distributor can provision.
paths:
  /v1/distributor-customers/{distributor-customer}/entitlements:
    get:
      tags:
        - Entitlements
      summary: List entitlements
      description: |-
        Retrieves the 1Password product entitlements for a distributor customer.
        To scope results to one customer, use the customer ID in the path (for example,
        `distributor-customers/{customer_id}`). To list entitlements across all of the
        distributor's customers, use the `-` wildcard (`distributor-customers/-`).
        Supports pagination and optional filtering.
      operationId: listDistributorEntitlements
      parameters:
        - name: distributor-customer
          in: path
          description: The customer ID to list entitlements for. Use the `-` wildcard to list across all of the distributor's customers. Each returned entitlement includes its own customer ID.
          required: true
          example: "-"
          schema:
            type: string
        - name: max_page_size
          in: query
          description: The maximum number of entitlements to return per page. Defaults to 100 when omitted or set to 0. Values greater than 100 are clamped to 100. Negative values return an `invalid_argument` error.
          schema:
            type: integer
            minimum: 0
            format: int32
        - name: page_token
          in: query
          description: The pagination token that identifies the page of results to return. Tokens don't expire and must be treated as opaque.
          schema:
            type: string
        - name: filter
          in: query
          description: An optional filter in CEL syntax (for example, `status == 'active'`). When omitted, entitlements of all statuses are returned.
          example: status == 'active'
          schema:
            type: string
      responses:
        "200":
          description: A paginated list of the customer's entitlements.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/distributor.v1.ListDistributorEntitlementsResponse'
              example:
                results:
                  - path: distributor-customers/cust_789xyz/entitlements/ent_abc123def456
                    id: ent_abc123def456
                    customer_id: cust_789xyz
                    product_id: 1p-msp-us
                    status: active
                    contact_info:
                      email: admin@acme-corp.com
                      company_name: Acme Corporation
                    create_time: "2026-09-15T10:30:00Z"
                    expire_time: "2026-09-20T10:30:00Z"
                next_page_token: ""
        "400":
          $ref: '#/components/responses/BadRequest'
        "401":
          $ref: '#/components/responses/Unauthenticated'
        "404":
          $ref: '#/components/responses/NotFound'
        "429":
          $ref: '#/components/responses/TooManyRequests'
        "500":
          $ref: '#/components/responses/Internal'
    post:
      tags:
        - Entitlements
      summary: Create an entitlement
      description: Provisions a new 1Password product entitlement for a distributor customer.
      operationId: CreateDistributorEntitlement
      parameters:
        - name: distributor-customer
          in: path
          description: The customer ID, as defined in the distributor's own system.
          required: true
          schema:
            type: string
      requestBody:
        required: true
        description: The entitlement resource to create.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/distributor.v1.DistributorEntitlement'
            example:
              product_id: 1p-msp-us
              contact_info:
                email: admin@acme-corp.com
                company_name: Acme Corporation
      responses:
        "200":
          description: The newly created entitlement, with status `pending`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/distributor.v1.DistributorEntitlement'
              example:
                path: distributor-customers/cust_789xyz/entitlements/ent_abc123def456
                id: ent_abc123def456
                customer_id: cust_789xyz
                product_id: 1p-msp-us
                status: pending
                contact_info:
                  email: admin@acme-corp.com
                  company_name: Acme Corporation
                create_time: "2026-09-15T10:30:00Z"
        "400":
          $ref: '#/components/responses/BadRequest'
        "401":
          $ref: '#/components/responses/Unauthenticated'
        "404":
          $ref: '#/components/responses/NotFound'
        "409":
          $ref: '#/components/responses/AlreadyExists'
        "429":
          $ref: '#/components/responses/TooManyRequests'
        "500":
          $ref: '#/components/responses/Internal'
  /v1/distributor-customers/{distributor-customer}/entitlements/{entitlement}:
    delete:
      tags:
        - Entitlements
      summary: Cancel an entitlement
      description: |-
        Initiates cancellation of a 1Password product entitlement for a distributor customer.
        The entitlement's status transitions to `cancelling` immediately. Background processing
        then completes the cancellation and transitions the status to `cancelled`.
      operationId: DeleteDistributorEntitlement
      parameters:
        - name: distributor-customer
          in: path
          description: The customer ID, as defined in the distributor's own system.
          required: true
          schema:
            type: string
        - name: entitlement
          in: path
          description: The entitlement ID.
          required: true
          schema:
            type: string
      responses:
        "200":
          description: The entitlement whose cancellation was initiated, with status `cancelling`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/distributor.v1.DistributorEntitlement'
              example:
                path: distributor-customers/cust_789xyz/entitlements/ent_abc123def456
                id: ent_abc123def456
                customer_id: cust_789xyz
                product_id: 1p-msp-us
                status: cancelling
                contact_info:
                  email: admin@acme-corp.com
                  company_name: Acme Corporation
                create_time: "2026-09-15T10:30:00Z"
        "401":
          $ref: '#/components/responses/Unauthenticated'
        "404":
          $ref: '#/components/responses/NotFound'
        "429":
          $ref: '#/components/responses/TooManyRequests'
        "500":
          $ref: '#/components/responses/Internal'
    patch:
      tags:
        - Entitlements
      summary: Update an entitlement
      description: |-
        Updates a pending 1Password product entitlement for a distributor customer.
        Only entitlements with a status of `pending` can be updated. Attempting to update
        an entitlement with any other status returns an error.
      operationId: UpdateDistributorEntitlement
      parameters:
        - name: distributor-customer
          in: path
          description: The customer ID, as defined in the distributor's own system.
          required: true
          schema:
            type: string
        - name: entitlement
          in: path
          description: The entitlement ID.
          required: true
          schema:
            type: string
        - name: update_mask
          in: query
          description: 'An optional comma-separated list of fields to update. If omitted, any supported fields provided in the request body are updated. Supported values: `contact_info.email`, `contact_info.company_name`, `contact_info`, and `*`.'
          example: contact_info.email
          schema:
            type: string
      requestBody:
        description: The entitlement resource containing the updated field values.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/distributor.v1.DistributorEntitlement'
            example:
              contact_info:
                email: new-admin@acme-corp.com
                company_name: Acme Corporation Ltd
      responses:
        "200":
          description: The updated entitlement.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/distributor.v1.DistributorEntitlement'
              example:
                path: distributor-customers/cust_789xyz/entitlements/ent_abc123def456
                id: ent_abc123def456
                customer_id: cust_789xyz
                product_id: 1p-msp-us
                status: pending
                contact_info:
                  email: new-admin@acme-corp.com
                  company_name: Acme Corporation Ltd
                create_time: "2026-09-15T10:30:00Z"
        "400":
          $ref: '#/components/responses/BadRequest'
        "401":
          $ref: '#/components/responses/Unauthenticated'
        "404":
          $ref: '#/components/responses/NotFound'
        "429":
          $ref: '#/components/responses/TooManyRequests'
        "500":
          $ref: '#/components/responses/Internal'
  /v1/distributor-customers/{distributor-customer}/entitlements:link:
    post:
      tags:
        - Entitlements
      summary: Link an entitlement
      description: Creates a change-of-channel entitlement to link a customer's existing 1Password account to the distributor.
      operationId: linkEntitlement
      parameters:
        - name: distributor-customer
          in: path
          description: The customer ID, as defined in the distributor's own system.
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/distributor.v1.LinkEntitlementRequest'
            example:
              product_id: 1p-msp-us
              contact_info:
                email: admin@acme-corp.com
                company_name: Acme Corporation
              metadata:
                one_password_domain: acme-corp.1password.com
        required: true
      responses:
        "200":
          description: The linked change-of-channel entitlement.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/distributor.v1.LinkEntitlementResponse'
              example:
                entitlement:
                  path: distributor-customers/cust_789xyz/entitlements/ent_link789abc
                  id: ent_link789abc
                  customer_id: cust_789xyz
                  product_id: 1p-msp-us
                  status: pending
                  contact_info:
                    email: admin@acme-corp.com
                    company_name: Acme Corporation
                  create_time: "2026-09-15T10:30:00Z"
                  expire_time: "2026-09-20T10:30:00Z"
        "400":
          $ref: '#/components/responses/BadRequest'
        "401":
          $ref: '#/components/responses/Unauthenticated'
        "404":
          $ref: '#/components/responses/NotFound'
        "409":
          $ref: '#/components/responses/AlreadyExists'
        "429":
          $ref: '#/components/responses/TooManyRequests'
        "500":
          $ref: '#/components/responses/Internal'
  /v1/distributor-customers/{distributor-customer}/usage:
    get:
      tags:
        - Usage
      summary: List customer usage
      description: |-
        Retrieves paginated product usage data for a distributor's customers.
        To scope results to one customer, use the customer ID in the path (for example,
        `distributor-customers/{customer_id}`). To list usage across all of the
        distributor's customers, use the `-` wildcard (`distributor-customers/-`).
      operationId: listCustomerUsages
      parameters:
        - name: distributor-customer
          in: path
          description: The customer ID, as defined in the distributor's own system, or the `-` wildcard to list usage across all of the distributor's customers.
          required: true
          example: "-"
          schema:
            type: string
        - name: filter
          in: query
          description: |-
            An optional filter that limits usage to a billing cycle, using the format `billing_cycle == 'YYYY-MM'` (for example, `billing_cycle == '2026-04'`). Other filter fields aren't supported.

            When omitted, usage defaults to the current billing cycle in UTC. There's no lookback limit on historical billing cycles.
          example: billing_cycle == '2026-09'
          schema:
            type: string
        - name: max_page_size
          in: query
          description: The maximum number of customer usage records to return per page. Defaults to 100 when omitted or set to 0. Values greater than 100 are clamped to 100. Negative values return an `invalid_argument` error.
          schema:
            type: integer
            minimum: 0
            format: int32
        - name: page_token
          in: query
          description: The pagination token that identifies the page of results to return. Tokens don't expire and must be treated as opaque.
          schema:
            type: string
      responses:
        "200":
          description: A paginated list of customer usage records.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/distributor.v1.ListCustomerUsagesResponse'
              example:
                results:
                  - customer_id: cust_789xyz
                    products:
                      - product_id: 1p-msp-us
                        quantity: 25
                        unit: net_seats
                        onepassword_account_id: op_acc_xyz456
                    billing_cycle: "2026-09"
                  - customer_id: cust_456def
                    products:
                      - product_id: 1p-msp-us
                        quantity: 100
                        unit: net_seats
                        onepassword_account_id: op_acc_xyz789
                    billing_cycle: "2026-09"
                next_page_token: cursor_next_page_abc
        "400":
          $ref: '#/components/responses/BadRequest'
        "401":
          $ref: '#/components/responses/Unauthenticated'
        "404":
          $ref: '#/components/responses/NotFound'
        "429":
          $ref: '#/components/responses/TooManyRequests'
        "500":
          $ref: '#/components/responses/Internal'
  /v1/distributor-products:
    get:
      tags:
        - Products
      summary: List products
      description: Retrieves the 1Password products available for a distributor to provision.
      operationId: listProducts
      parameters:
        - name: max_page_size
          in: query
          description: The maximum number of products to return per page. Defaults to 100 when omitted or set to 0. Values greater than 100 are clamped to 100. Negative values return an `invalid_argument` error.
          schema:
            type: integer
            minimum: 0
            format: int32
        - name: page_token
          in: query
          description: The pagination token that identifies the page of results to return. Tokens don't expire and must be treated as opaque.
          schema:
            type: string
      responses:
        "200":
          description: A paginated list of products available to the distributor.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/distributor.v1.ListProductsResponse'
              example:
                results:
                  - name: 1Password MSP
                    product_id: 1p-msp-us
                next_page_token: ""
        "400":
          $ref: '#/components/responses/BadRequest'
        "401":
          $ref: '#/components/responses/Unauthenticated'
        "404":
          $ref: '#/components/responses/NotFound'
        "429":
          $ref: '#/components/responses/TooManyRequests'
        "500":
          $ref: '#/components/responses/Internal'
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        Bearer token authentication. When a distributor is registered, they
        receive an opaque bearer token (prefixed `op_b_`). Include it in the
        Authorization header of every request as `Bearer <token>`.
  responses:
    BadRequest:
      description: Bad Request - Invalid parameters.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: invalid_argument
            message: The 'email' field must be a valid email address.
    Unauthenticated:
      description: Unauthenticated - Missing or invalid credentials.
      headers:
        WWW-Authenticate:
          description: The authentication scheme to use ("Bearer").
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: unauthenticated
            message: Authentication required. Please provide a valid bearer token.
    NotFound:
      description: Not Found - Resource does not exist.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: not_found
            message: The requested resource was not found.
    AlreadyExists:
      description: Conflict - Resource already exists.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: already_exists
            message: An entitlement for this product already exists.
    Internal:
      description: Internal Server Error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: internal
            message: An internal error occurred. Please try again later.
    TooManyRequests:
      description: Too Many Requests - Limit is 1,000 requests per minute per distributor. There is no separate hourly limit.
      headers:
        Retry-After:
          description: How long to wait before retrying, in seconds.
          schema:
            type: string
      content:
        text/plain:
          schema:
            type: string
          example: "Too Many Requests"
  schemas:
    Error:
      type: object
      properties:
        code:
          type: string
          description: Error code.
          example: not_found
        message:
          type: string
          description: Human-readable message.
          example: The requested resource was not found.
      required:
        - code
        - message
      description: Standard error response format.
    distributor.v1.DistributorContactInfo:
      type: object
      properties:
        email:
          type: string
          format: email
          description: The customer's contact email for account activation.
        company_name:
          type: string
          minLength: 1
          description: The customer's organization name.
      required:
        - email
        - company_name
      additionalProperties: false
      description: The customer contact details used for account setup.
      x-aep-resource:
        singular: distributorcontactinfo
    distributor.v1.DistributorCustomerUsage:
      type: object
      properties:
        customer_id:
          type: string
          description: The unique identifier for the marketplace customer. This is the distributor-defined ID used when creating the customer's entitlement.
        products:
          type: array
          items:
            $ref: '#/components/schemas/distributor.v1.DistributorProductUsage'
          description: The list of 1Password products and their usage.
        billing_cycle:
          type: string
          description: The billing cycle for the returned usage data. Historical billing cycles have no lookback limit.
      additionalProperties: false
      description: A customer identifier paired with the customer's product usage data.
      x-aep-resource:
        singular: distributorcustomerusage
    distributor.v1.DistributorEntitlement:
      type: object
      properties:
        path:
          type: string
          description: The canonical resource path of the entitlement (for example, "distributor-customers/{customer_id}/entitlements/{id}"). Use the IDs in this path to update or cancel the entitlement.
          readOnly: true
        id:
          type: string
          description: The unique identifier for this entitlement.
          readOnly: true
        customer_id:
          type: string
          description: The ID of the marketplace customer who owns this entitlement. This is the distributor-defined ID from the request path that created the entitlement.
          readOnly: true
        product_id:
          type: string
          description: The ID of the 1Password product. Required on create; immutable thereafter.
        status:
          type: string
          description: The entitlement lifecycle state.
          enum:
            - pending
            - active
            - cancelling
            - cancelled
            - expired
            - suspended
          readOnly: true
        contact_info:
          description: The customer's contact details for account setup.
          $ref: '#/components/schemas/distributor.v1.DistributorContactInfo'
        create_time:
          description: The date and time the entitlement was created.
          type: string
          format: date-time
          readOnly: true
        expire_time:
          description: The date and time the entitlement expires. Set only for change-of-channel entitlements created by linking an entitlement, and omitted for standard entitlements. Customers have 5 days to claim the emailed entitlement code against their existing 1Password account. Claiming the code completes the link; otherwise, the entitlement transitions to `expired` at this time.
          type: string
          format: date-time
          readOnly: true
      additionalProperties: false
      description: A provisioned 1Password product entitlement for a distributor customer.
      x-aep-resource:
        singular: distributorentitlement
    distributor.v1.DistributorMetadata:
      type: object
      properties:
        one_password_domain:
          type: string
          minLength: 1
          description: The 1Password domain of the customer's existing 1Password account (for example, `acme-corp.1password.com`). The domain can only be updated if the entitlement already has a domain set; it can't be added or removed.
      additionalProperties: false
      description: Auxiliary fields for change-of-channel entitlement flows.
      required:
        - one_password_domain
      x-aep-resource:
        singular: distributormetadata
    distributor.v1.DistributorProduct:
      type: object
      properties:
        name:
          type: string
          description: The display name of the 1Password product.
          example: 1Password MSP
        product_id:
          type: string
          description: The unique identifier for the product. Use this value when creating entitlements.
          example: 1p-msp-us
      additionalProperties: false
      description: A 1Password product that a distributor can provision.
      x-aep-resource:
        singular: distributorproduct
    distributor.v1.DistributorProductUsage:
      type: object
      properties:
        product_id:
          type: string
          minLength: 1
          description: The ID of the 1Password product.
        quantity:
          type: integer
          format: int32
          description: The count of the product for the billing cycle. A quantity of `0` is reported explicitly.
        unit:
          type: string
          minLength: 1
          description: How the quantity is calculated. Currently, the only unit is `net_seats`. Additional units may be introduced over time, so treat unrecognized values gracefully.
          example: net_seats
        onepassword_account_id:
          type: string
          minLength: 1
          description: The ID of the 1Password account associated with this usage.
      additionalProperties: false
      description: A single product's usage for a customer in a billing cycle.
      required:
        - product_id
        - unit
        - onepassword_account_id
      x-aep-resource:
        singular: distributorproductusage
    distributor.v1.LinkEntitlementRequest:
      type: object
      properties:
        product_id:
          type: string
          minLength: 1
          description: The ID of the 1Password product to provision.
        contact_info:
          description: The customer details for account activation and setup.
          $ref: '#/components/schemas/distributor.v1.DistributorContactInfo'
        metadata:
          description: The change-of-channel information. Required, and must include `one_password_domain`.
          $ref: '#/components/schemas/distributor.v1.DistributorMetadata'
      required:
        - contact_info
        - metadata
        - product_id
      additionalProperties: false
      description: The request body for linking an existing 1Password account.
    distributor.v1.LinkEntitlementResponse:
      type: object
      properties:
        entitlement:
          description: The linked entitlement.
          $ref: '#/components/schemas/distributor.v1.DistributorEntitlement'
      additionalProperties: false
      description: The response for a successful entitlement link.
    distributor.v1.ListCustomerUsagesResponse:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/distributor.v1.DistributorCustomerUsage'
          description: The list of customers with their usage data for the billing cycle.
        next_page_token:
          type: string
          description: The token to use for the next page of results. Empty if there are no more results.
      additionalProperties: false
      description: The paginated usage data for the requested customers.
    distributor.v1.ListDistributorEntitlementsResponse:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/distributor.v1.DistributorEntitlement'
          description: The list of entitlements under the customer, or under all customers when using the `-` wildcard.
        next_page_token:
          type: string
          description: The token to use for the next page of results. Empty if there are no more results.
      additionalProperties: false
      description: The paginated list of entitlements.
    distributor.v1.ListProductsResponse:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/distributor.v1.DistributorProduct'
          description: The list of products available to the distributor.
        next_page_token:
          type: string
          description: The token to use for the next page of results. Empty if there are no more results.
      additionalProperties: false
      description: The paginated product catalog available to the distributor.
security:
  - BearerAuth: []
