grafomem-com Portal API

Tenant portal authentication

Operations 12

POST /v1/portal/signup Signup #
POST /v1/portal/login Login #
POST /v1/portal/sync Sync Tenant #
GET /v1/portal/me Get Dashboard #
POST /v1/portal/api-keys Create Api Key #
DELETE /v1/portal/api-keys/{key_id} Revoke Api Key #
POST /v1/portal/profile Update Profile #
POST /v1/portal/change-password Change Password #
POST /v1/portal/rotate-key Rotate Key #
GET /v1/portal/audit Get Audit Logs #
POST /v1/portal/upgrade Upgrade #
POST /v1/portal/portal Portal #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/grafomem-com:grafomem-com-portal-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

grafomem-com-portal-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: GRAFOMEM Cloud Portal API
  description: GMP-conformant governed agent memory platform. Provides vector-backed memory stores, multi-agent orchestration, decision trail audit logging, erasure proof certificates, governance policy evaluation, regulatory reports, webhook alerts, SSO/OIDC, and real-time SSE streaming.
  version: 1.9.0
tags:
- name: Portal
  description: Tenant portal authentication
paths:
  /v1/portal/signup:
    post:
      tags:
      - Portal
      summary: Signup
      description: Create a new tenant account with email/password credentials.
      operationId: signup_v1_portal_signup_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignupRequest'
        required: true
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/portal/login:
    post:
      tags:
      - Portal
      summary: Login
      description: Authenticate with email and password, receive JWT.
      operationId: login_v1_portal_login_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/portal/sync:
    post:
      tags:
      - Portal
      summary: Sync Tenant
      description: 'Auto-provision a tenant after Supabase login.


        Called by the frontend after a successful Supabase auth (signup, OAuth,

        or email confirmation). Verifies the Supabase JWT from the Authorization

        header, then finds-or-creates the linked tenant.'
      operationId: sync_tenant_v1_portal_sync_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SyncRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/portal/me:
    get:
      tags:
      - Portal
      summary: Get Dashboard
      description: Fetch aggregated dashboard data for the authenticated tenant.
      operationId: get_dashboard_v1_portal_me_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DashboardResponse'
  /v1/portal/api-keys:
    post:
      tags:
      - Portal
      summary: Create Api Key
      description: 'Mint a scoped API key for the signed-in tenant.


        Two shapes:

        * `{"name", "role"}` (no `scopes`) — today''s behaviour: `admin` mints TENANT_ADMIN_SCOPES, `agent` and

        `read_only` their bounded role defaults. `role` defaults to `admin`.

        * `{"name", "scopes": [...]}` — a NARROW key carrying exactly the named scopes (e.g. the analyst''s

        submit key: `["disposition:write", "disposition:read"]`). The list must be non-empty, in the

        vocabulary, and a subset of TENANT_ADMIN_SCOPES; otherwise 400 naming the refused scopes and

        nothing is minted. `role` defaults to `agent` (it only sets the key prefix; the stored scopes are

        the explicit list, which the resolver never widens).

        The response is unchanged: `{api_key (show-once), key_id, role, scopes, expires_at}`.'
      operationId: create_api_key_v1_portal_api_keys_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateApiKeyRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/portal/api-keys/{key_id}:
    delete:
      tags:
      - Portal
      summary: Revoke Api Key
      description: 'Revoke (delete) a SINGLE API key by key_id — tenant-scoped, non-destructive to other keys.


        The per-key counterpart to /rotate-key (which deletes every key). Scoped by tenant_id, so a key_id

        belonging to another tenant simply matches no row → 404 (never touches, never reveals it). Evicts

        the auth cache so the revoked key stops resolving within the 60s TTL, not only in the DB.'
      operationId: revoke_api_key_v1_portal_api_keys__key_id__delete
      parameters:
      - name: key_id
        in: path
        required: true
        schema:
          type: string
          title: Key Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/portal/profile:
    post:
      tags:
      - Portal
      summary: Update Profile
      description: 'Update the signed-in user''s editable profile (display name). Auth: portal

        session; acts only on the caller''s tenant. Email/plan are read-only.'
      operationId: update_profile_v1_portal_profile_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateProfileRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/portal/change-password:
    post:
      tags:
      - Portal
      summary: Change Password
      description: 'Change the signed-in user''s password. Re-verifies the current password before

        setting the new one. Auth: portal session (JWT); acts only on the caller''s tenant.'
      operationId: change_password_v1_portal_change_password_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChangePasswordRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/portal/rotate-key:
    post:
      tags:
      - Portal
      summary: Rotate Key
      description: Revoke the current API key and issue a new one.
      operationId: rotate_key_v1_portal_rotate_key_post
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
  /v1/portal/audit:
    get:
      tags:
      - Portal
      summary: Get Audit Logs
      description: Retrieve immutable audit logs for the tenant.
      operationId: get_audit_logs_v1_portal_audit_get
      parameters:
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          default: 100
          title: Limit
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/portal/upgrade:
    post:
      tags:
      - Portal
      summary: Upgrade
      description: Initiate Stripe Checkout for a plan upgrade.
      operationId: upgrade_v1_portal_upgrade_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpgradeRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/portal/portal:
    post:
      tags:
      - Portal
      summary: Portal
      description: Initiate Stripe Customer Portal session.
      operationId: portal_v1_portal_portal_post
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
components:
  schemas:
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ComplianceOut:
      properties:
        conformance_rate:
          anyOf:
          - type: number
          - type: 'null'
          title: Conformance Rate
        capabilities:
          items:
            type: string
          type: array
          title: Capabilities
        audited_at:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Audited At
      type: object
      title: ComplianceOut
      description: Latest conformance snapshot.
    UpdateProfileRequest:
      properties:
        name:
          type: string
          title: Name
        timezone:
          anyOf:
          - type: string
          - type: 'null'
          title: Timezone
      type: object
      required:
      - name
      title: UpdateProfileRequest
      description: Editable profile fields (display name + IANA timezone; email/plan read-only).
    SignupRequest:
      properties:
        name:
          type: string
          title: Name
        email:
          type: string
          title: Email
        password:
          type: string
          title: Password
        plan:
          type: string
          title: Plan
          default: starter
      type: object
      required:
      - name
      - email
      - password
      title: SignupRequest
      description: Portal signup payload.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    BillingOut:
      properties:
        plan:
          type: string
          title: Plan
          default: starter
        status:
          type: string
          title: Status
          default: active
        current_period_end:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Current Period End
      type: object
      title: BillingOut
      description: Current billing / subscription status.
    CreateApiKeyRequest:
      properties:
        name:
          type: string
          title: Name
          default: custom_key
        role:
          anyOf:
          - type: string
          - type: 'null'
          title: Role
        expires_at:
          anyOf:
          - type: integer
          - type: 'null'
          title: Expires At
        ip_allowlist:
          anyOf:
          - items:
              type: string
            type: array
          - type: 'null'
          title: Ip Allowlist
        scopes:
          anyOf:
          - items:
              type: string
            type: array
          - type: 'null'
          title: Scopes
      type: object
      title: CreateApiKeyRequest
    TokenResponse:
      properties:
        token:
          type: string
          title: Token
        tenant_id:
          type: string
          title: Tenant Id
        name:
          type: string
          title: Name
        email:
          type: string
          title: Email
        api_key:
          anyOf:
          - type: string
          - type: 'null'
          title: Api Key
        plan:
          type: string
          title: Plan
      type: object
      required:
      - token
      - tenant_id
      - name
      - email
      - plan
      title: TokenResponse
      description: 'Returned after successful signup or login.


        ``api_key`` is present only on the show-once signup response. A login response carries no key

        (no plaintext is stored; hash-at-rest): the field is null and the client provisions one via

        /v1/portal/api-keys or /rotate-key.'
    UpgradeRequest:
      properties:
        plan:
          type: string
          title: Plan
          default: pro
      type: object
      title: UpgradeRequest
      description: Plan upgrade payload.
    UsageSummaryOut:
      properties:
        writes:
          type: integer
          title: Writes
          default: 0
        reads:
          type: integer
          title: Reads
          default: 0
        deletes:
          type: integer
          title: Deletes
          default: 0
        supersedes:
          type: integer
          title: Supersedes
          default: 0
        total_bytes:
          type: integer
          title: Total Bytes
          default: 0
        total_operations:
          type: integer
          title: Total Operations
          default: 0
      type: object
      title: UsageSummaryOut
      description: Usage stats for the dashboard.
    LoginRequest:
      properties:
        email:
          type: string
          title: Email
        password:
          type: string
          title: Password
      type: object
      required:
      - email
      - password
      title: LoginRequest
      description: Portal login payload.
    SyncRequest:
      properties:
        name:
          type: string
          title: Name
          default: ''
        plan:
          type: string
          title: Plan
          default: starter
      type: object
      title: SyncRequest
      description: Tenant sync payload — sent after first Supabase login.
    ApiKeyMeta:
      properties:
        key_id:
          type: string
          title: Key Id
        name:
          anyOf:
          - type: string
          - type: 'null'
          title: Name
        role:
          anyOf:
          - type: string
          - type: 'null'
          title: Role
        scopes:
          items:
            type: string
          type: array
          title: Scopes
        created_at:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Created At
        last_used_at:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Last Used At
        expires_at:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Expires At
      type: object
      required:
      - key_id
      title: ApiKeyMeta
      description: 'Non-secret metadata for one tenant_api_keys row — NEVER the key itself.

        014 step (a): the console lists keys by metadata; the full key is shown only at

        mint/rotate (the create/rotate response bodies), never on /me.'
    DashboardResponse:
      properties:
        tenant_id:
          type: string
          title: Tenant Id
        name:
          type: string
          title: Name
        email:
          type: string
          title: Email
        keys:
          items:
            $ref: '#/components/schemas/ApiKeyMeta'
          type: array
          title: Keys
        plan:
          type: string
          title: Plan
        timezone:
          anyOf:
          - type: string
          - type: 'null'
          title: Timezone
        usage:
          $ref: '#/components/schemas/UsageSummaryOut'
        compliance:
          anyOf:
          - $ref: '#/components/schemas/ComplianceOut'
          - type: 'null'
        billing:
          anyOf:
          - $ref: '#/components/schemas/BillingOut'
          - type: 'null'
      type: object
      required:
      - tenant_id
      - name
      - email
      - plan
      - usage
      title: DashboardResponse
      description: Aggregated dashboard data returned by ``GET /v1/portal/me``.
    ChangePasswordRequest:
      properties:
        current_password:
          type: string
          title: Current Password
        new_password:
          type: string
          title: New Password
      type: object
      required:
      - current_password
      - new_password
      title: ChangePasswordRequest
      description: 'Authenticated password change: current password re-verified, new one set.'