Ultrahuman OAuth API

OAuth 2.0 authorization, token exchange, and revocation.

OpenAPI Specification

ultrahuman-oauth-api-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Ultrahuman Partner (UltraSignal) Metrics OAuth API
  description: 'The Ultrahuman Partner API gives approved partners read access to user-consented health metrics from the Ultrahuman Ring AIR / Ring Pro and, for users with an active M1 patch, the Ultrahuman CGM. Access is secured with OAuth 2.0 (Authorization Code Grant plus Refresh Token flow) across three scopes: profile, ring_data, and cgm_data. Access is not self-serve - partners apply to the developer program and are issued a Client ID, Client Secret, and a registered redirect URI during onboarding; end users authorize data sharing from the Ultrahuman app (Profile -> Settings -> Partner ID). Access tokens expire in ~1 day (86400 seconds); refresh tokens rotate on each exchange.

    IMPORTANT: This document is MODELED by API Evangelist from Ultrahuman''s public partner developer documentation. Endpoint paths, scopes, OAuth flows, query parameters, and the documented metric families are drawn from the docs; exact request/response schemas are approximations and should be verified against the live developer portal. Ultrahuman also documents a personal-token variant at GET /api/v1/partner/daily_metrics for a developer''s own ring data.'
  version: '1.0'
  contact:
    name: Ultrahuman Partnerships
    url: https://partnerships.ultrahuman.com/
  x-endpointsModeled: true
servers:
- url: https://partner.ultrahuman.com
  description: Ultrahuman Partner API
tags:
- name: OAuth
  description: OAuth 2.0 authorization, token exchange, and revocation.
paths:
  /authorize:
    get:
      operationId: authorize
      tags:
      - OAuth
      summary: Authorization endpoint (Authorization Code Grant)
      description: Redirects the user to Ultrahuman to consent to the requested scopes. On approval, Ultrahuman redirects back to the registered redirect_uri with an authorization code.
      parameters:
      - name: response_type
        in: query
        required: true
        schema:
          type: string
          enum:
          - code
      - name: client_id
        in: query
        required: true
        schema:
          type: string
      - name: redirect_uri
        in: query
        required: true
        schema:
          type: string
          format: uri
      - name: scope
        in: query
        required: true
        description: Space-delimited scopes - profile, ring_data, cgm_data.
        schema:
          type: string
          example: profile ring_data cgm_data
      - name: state
        in: query
        required: false
        schema:
          type: string
      responses:
        '302':
          description: Redirect to redirect_uri with an authorization code (or an error).
  /api/partners/oauth/token:
    post:
      operationId: token
      tags:
      - OAuth
      summary: Token endpoint (code exchange and refresh)
      description: Exchanges an authorization code for an access token, or exchanges a refresh token for a new access token. Perform token exchanges server-side. Refresh tokens rotate on each exchange.
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/TokenRequest'
      responses:
        '200':
          description: A new access token (and rotated refresh token).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /api/partners/oauth/revoke:
    post:
      operationId: revoke
      tags:
      - OAuth
      summary: Revoke a token
      description: Revokes an access or refresh token.
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
              - token
              - client_id
              - client_secret
              properties:
                token:
                  type: string
                client_id:
                  type: string
                client_secret:
                  type: string
      responses:
        '200':
          description: Token revoked.
        '400':
          $ref: '#/components/responses/BadRequest'
components:
  responses:
    BadRequest:
      description: Invalid parameters, or the epoch window exceeded the 7-day limit.
    Unauthorized:
      description: Missing, invalid, or expired access token.
  schemas:
    TokenRequest:
      type: object
      required:
      - grant_type
      - client_id
      - client_secret
      properties:
        grant_type:
          type: string
          enum:
          - authorization_code
          - refresh_token
        client_id:
          type: string
        client_secret:
          type: string
        code:
          type: string
          description: Required for grant_type=authorization_code.
        redirect_uri:
          type: string
          format: uri
        refresh_token:
          type: string
          description: Required for grant_type=refresh_token.
    TokenResponse:
      type: object
      properties:
        access_token:
          type: string
        token_type:
          type: string
          example: Bearer
        expires_in:
          type: integer
          example: 86400
        refresh_token:
          type: string
        scope:
          type: string
        created_at:
          type: integer
          format: int64
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: OAuth 2.0 access token in the Authorization header.