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

# Issue or revoke a portal access token



## OpenAPI

````yaml /openapi.json post /admin/api/projects/{project_id}/portals/{portal_id}/tokens
openapi: 3.1.0
info:
  title: Hookie API
  version: 1.0.0
  summary: Capture, route and deliver webhooks.
  description: >-
    Hookie exposes three HTTP surfaces.


    **Ingest + streaming** is the public plane. A path-form endpoint URL
    authenticates by its own high-entropy slug — there is no key, token or
    cookie — and an `ik_live_…` ingest key authenticates the `/v1/*` routes.
    Whenever the URL names a dataset the payload is stored whole into it;
    project mapping rules are evaluated on exactly one shape, `POST
    /v1/ingest/{ingest_key}` with no dataset segment.


    **The customer portal API** is a separate, token-authed surface for your end
    customers, scoped to one portal and one customer.


    **The admin API** drives the console. It accepts either a browser session or
    an OAuth bearer token from a connected coding agent — the same routes, the
    same validation, the same audit trail. An agent's authority is its user's
    workspace role narrowed to the scopes granted in the console.


    This document is generated from the request handlers and adversarially
    verified against them.
  contact:
    name: Hookie
    url: https://hookie.ai
  license:
    name: Proprietary
    url: https://hookie.ai/legal/terms
servers:
  - url: https://app.hookie.ai
    description: Production
  - url: https://app.preview.hookie.ai
    description: Preview
security: []
tags:
  - name: Ingest
    description: Send events to Hookie.
  - name: Streaming
    description: Tail events in real time over SSE or WebSocket.
  - name: Portal
    description: Token-authed surface for your end customers.
  - name: Projects
    description: Projects and their settings.
  - name: Routing
    description: Rules, endpoints, datasets and records.
  - name: Delivery
    description: Destinations, deliveries and replay.
  - name: Workflows
    description: Multi-step workflows, triggers and AI agents.
  - name: Observability
    description: Search, correlation, stats and the audit log.
  - name: Workspace
    description: Members, connected agents, SSO and billing.
paths:
  /admin/api/projects/{project_id}/portals/{portal_id}/tokens:
    post:
      tags:
        - Portals
      summary: Issue or revoke a portal access token
      operationId: issuePortalToken
      parameters:
        - name: project_id
          in: path
          required: true
          schema:
            type: string
        - name: portal_id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              description: >-
                One endpoint, two modes, discriminated by the presence of a
                string `revoke`.
              oneOf:
                - title: Issue
                  type: object
                  required:
                    - customer_id
                  properties:
                    customer_id:
                      type: string
                      minLength: 1
                      description: >-
                        The tenant's own identifier for their end customer.
                        Trimmed; must be non-empty.
                    scopes:
                      type: array
                      items:
                        type: string
                      default: []
                      description: >-
                        Stored on the token but not enforced by the portal API
                        today.
                    expires_in_days:
                      type: number
                      description: >-
                        Must be finite and > 0 to take effect; anything else
                        means the token never expires.
                - title: Revoke
                  type: object
                  required:
                    - revoke
                  properties:
                    revoke:
                      type: string
                      description: >-
                        Id of a token belonging to this portal. Sets revoked_at;
                        already-revoked tokens are treated as not found.
      responses:
        '200':
          description: Revoke mode only — the token was revoked.
          content:
            application/json:
              schema:
                type: object
                required:
                  - ok
                properties:
                  ok:
                    type: boolean
                    enum:
                      - true
        '201':
          description: >-
            Issue mode — the plaintext token is returned ONCE and is never
            retrievable again.
          content:
            application/json:
              schema:
                type: object
                required:
                  - id
                  - token
                  - expires_at
                properties:
                  id:
                    type: string
                  token:
                    type: string
                    description: >-
                      'hpt_' plus 48 hex characters. Presented by the end
                      customer as `Authorization: Bearer <token>` or a `?token=`
                      query parameter.
                  expires_at:
                    type:
                      - string
                      - 'null'
                    format: date-time
        '400':
          description: >-
            `customer_id is required` — issue mode with no non-empty customer_id
            and no `revoke`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not signed in.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: >-
            `Insufficient role` (write capability required), or `Missing
            X-Requested-With header`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: >-
            `Portal not found`, `Token not found` (revoke mode), or `Project not
            found`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: '`Internal error`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - session: []
        - bearerAuth: []
components:
  schemas:
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: Human-readable reason.
        retry_after:
          type: integer
          description: Seconds to wait. Present on 429.
        upgrade_url:
          type: string
          format: uri
          description: Present only on a monthly-quota 429.
  securitySchemes:
    session:
      type: apiKey
      in: cookie
      name: hookie_session
      description: >-
        The console's sealed session cookie, set by WorkOS AuthKit. Mutating
        requests also require the `X-Requested-With` CSRF header.
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        An OAuth 2.1 access token from a connected agent, audienced at the
        `/mcp` resource URI. The agent acts as its user, with that user's role
        narrowed to the granted `hookie:*` scopes. No CSRF header is required —
        a bearer token is not ambient credentials.

````