> ## Documentation Index
> Fetch the complete documentation index at: https://guide.mylifenote.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Exchange a code or refresh a token

> Public-client token endpoint (no client secret; `token_endpoint_auth_methods_supported` is `none`). Accepts `application/x-www-form-urlencoded` (RFC 6749) or `application/json`. Access tokens (`lna_...`) live 1 hour; refresh tokens (`lnr_...`) live 30 days. Refresh tokens rotate: every refresh returns a new refresh token and the previous one stops working. Presenting an already-rotated refresh token revokes the whole token family, so always store the newest refresh token. The `client_id` is not required or checked at this endpoint. This endpoint is not covered by the per-token rate limits.



## OpenAPI

````yaml /api-reference/openapi.json post /oauth/token
openapi: 3.1.0
info:
  title: Life Note Agent API
  version: 1.0.0
  description: >-
    Read-only HTTP API for connecting AI agents and automation tools (such as
    Zapier) to a user's Life Note account. Authenticate with OAuth 2.0
    authorization code + PKCE (S256) and send the access token as
    `Authorization: Bearer <access_token>`. Journal content is decrypted
    server-side and returned only to the authorizing user's own token.
servers:
  - url: https://mylifenote.ai/api/agent/v1
    description: Production
security: []
tags:
  - name: OAuth
    description: Authorization and token exchange
  - name: Account
  - name: Journal
paths:
  /oauth/token:
    post:
      tags:
        - OAuth
      summary: Exchange a code or refresh a token
      description: >-
        Public-client token endpoint (no client secret;
        `token_endpoint_auth_methods_supported` is `none`). Accepts
        `application/x-www-form-urlencoded` (RFC 6749) or `application/json`.
        Access tokens (`lna_...`) live 1 hour; refresh tokens (`lnr_...`) live
        30 days. Refresh tokens rotate: every refresh returns a new refresh
        token and the previous one stops working. Presenting an already-rotated
        refresh token revokes the whole token family, so always store the newest
        refresh token. The `client_id` is not required or checked at this
        endpoint. This endpoint is not covered by the per-token rate limits.
      operationId: token
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              oneOf:
                - $ref: '#/components/schemas/AuthCodeGrant'
                - $ref: '#/components/schemas/RefreshGrant'
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/AuthCodeGrant'
                - $ref: '#/components/schemas/RefreshGrant'
      responses:
        '200':
          description: Token pair.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
              example:
                access_token: lna_EXAMPLEaccessTokenNotReal0000000000000000
                refresh_token: lnr_EXAMPLErefreshTokenNotReal000000000000000
                token_type: Bearer
                expires_in: 3600
                refresh_expires_in: 2592000
                scope: journal:read
        '400':
          description: >-
            `unsupported_grant_type` (missing or unknown `grant_type`),
            `invalid_request` (missing `code`, `redirect_uri`, `code_verifier`
            or `refresh_token`), or `invalid_grant` (code unknown, expired,
            already used, redirect_uri mismatch, PKCE failure, or refresh token
            unknown, expired, revoked or reused). `detail` is present only for
            redirect_uri mismatch and PKCE failure. A code is burned by its
            first exchange attempt even if that attempt fails.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                grant:
                  value:
                    error: invalid_grant
                pkce:
                  value:
                    error: invalid_grant
                    detail: pkce verification failed
                type:
                  value:
                    error: unsupported_grant_type
      security: []
components:
  schemas:
    AuthCodeGrant:
      type: object
      title: Authorization code grant
      required:
        - grant_type
        - code
        - redirect_uri
        - code_verifier
      properties:
        grant_type:
          type: string
          enum:
            - authorization_code
        code:
          type: string
          description: Code from the redirect. Valid 5 minutes, single use.
          example: lnoc_EXAMPLEcodeNotReal
        redirect_uri:
          type: string
          format: uri
          description: Must exactly equal the redirect_uri used in the authorize step.
        code_verifier:
          type: string
          description: The PKCE verifier whose S256 hash was sent as code_challenge.
          example: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
    RefreshGrant:
      type: object
      title: Refresh grant
      required:
        - grant_type
        - refresh_token
      properties:
        grant_type:
          type: string
          enum:
            - refresh_token
        refresh_token:
          type: string
          example: lnr_EXAMPLErefreshTokenNotReal
    TokenResponse:
      type: object
      required:
        - access_token
        - refresh_token
        - token_type
        - expires_in
        - refresh_expires_in
        - scope
      properties:
        access_token:
          type: string
          description: Prefix `lna_`.
        refresh_token:
          type: string
          description: Prefix `lnr_`. Replaces the previous refresh token.
        token_type:
          type: string
          enum:
            - Bearer
        expires_in:
          type: integer
          description: Access token lifetime in seconds (3600).
          example: 3600
        refresh_expires_in:
          type: integer
          description: Refresh token lifetime in seconds (2592000 = 30 days).
          example: 2592000
        scope:
          type: string
          description: Space-separated granted scopes.
          example: journal:read
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: Machine-readable code.
        detail:
          type: string
          description: Human-readable detail; not always present.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.