openapi: 3.2.0 info: title: 'GTM API public contract: gtm.service.id Billing Payment…' description: 'Identity, access and money: users, teams and members, API keys, OAuth clients and authorizations, billing products, subscriptions, transactions and payment methods, notifications, TLS certificates and support requests.' version: '1.0' contact: name: GTM API url: https://gtm-api.com email: support@gtm-api.com license: name: Proprietary url: https://gtm-api.com/license servers: - url: https://app.gtm-api.com/id/v4 description: Production, through the app.gtm-api.com gateway security: - BearerJwt: [] TeamSid: [] tags: - name: billing_payment_methods description: Registry package `mcp.id/billing_payment_methods`, served on MCP mount `id.billing`. paths: /api/billing-payment-methods: get: operationId: list_billing_payment_methods summary: List payment methods description: 'List the saved cards / PayPal / wallets for the active workspace''s paying user (proxied live from Paddle). The list is re-sorted so the billing card is items[0]; is_default:true is the card that last billed the workspace, so answer ''which card am I paying with'' by reading it. Cards may be listed even with no applied subscription; empty if the user has no Paddle customer. Brand + last4 + expiry only (PCI). Requires billing.view. Contract: - MCP tool `list_billing_payment_methods`, registry package `mcp.id/billing_payment_methods`, mount `id.billing`. - Operation `search`, response envelope `search`. - Flags: read only.' tags: - billing_payment_methods responses: '200': description: '`search` success envelope.' content: application/json: schema: $ref: '#/components/schemas/ListBillingPaymentMethodsResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: list_billing_payment_methods x-gtm-mcp-mount: id.billing x-gtm-entity: billing_payment_methods x-gtm-operation: search x-gtm-envelope: search x-gtm-availability: ga x-gtm-dangerous: false x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical /api/billing-payment-methods/get-add-link: post: operationId: get_billing_payment_method_add_link summary: Get add-card link description: 'Return a temporary Paddle Customer Portal deep link to add or replace a card for the workspace''s applied subscription. This is the ONLY way to add a card: Paddle has no add-card API; the user enters card details on Paddle''s hosted page. Never cached. Returns no_billing_account if the workspace has no applied subscription. Requires billing.manage. Contract: - MCP tool `get_billing_payment_method_add_link`, registry package `mcp.id/billing_payment_methods`, mount `id.billing`. - Operation `action`, response envelope `action`. - Flags: none.' tags: - billing_payment_methods responses: '200': description: '`action` success envelope.' content: application/json: schema: $ref: '#/components/schemas/GetBillingPaymentMethodAddLinkResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: get_billing_payment_method_add_link x-gtm-mcp-mount: id.billing x-gtm-entity: billing_payment_methods x-gtm-operation: action x-gtm-envelope: action x-gtm-availability: ga x-gtm-dangerous: false x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical /api/billing-payment-methods/{sid}: delete: operationId: delete_billing_payment_method summary: Delete payment method description: 'Remove a saved payment method: this only takes it off the paying user''s saved list in Paddle. A method a live subscription uses is refused (409 conflict, payment_method_in_use) until that subscription is moved to another card via get_billing_payment_method_add_link: always the case for is_default:true while the plan bills it. A non-default card can be refused too, when it pays another subscription of the same payer (another workspace or a floating one). Idempotent. Requires billing.manage. Contract: - MCP tool `delete_billing_payment_method`, registry package `mcp.id/billing_payment_methods`, mount `id.billing`. - Operation `delete`, response envelope `delete_simple`. - Flags: dangerous: the MCP layer gates it behind a preview/commit token, and the effect cannot be undone through this API.' tags: - billing_payment_methods parameters: - name: sid in: path required: true description: 'Paddle payment-method id (paymtd_…): a raw Paddle id, not an 18-char platform sid.' schema: type: string pattern: ^paymtd_ description: 'Paddle payment-method id (paymtd_…): a raw Paddle id, not an 18-char platform sid.' responses: '200': description: '`delete_simple` success envelope.' content: application/json: schema: $ref: '#/components/schemas/DeleteBillingPaymentMethodResponse' 4XX: $ref: '#/components/responses/McpClientError' 5XX: $ref: '#/components/responses/McpServerError' x-gtm-mcp-tool: delete_billing_payment_method x-gtm-mcp-mount: id.billing x-gtm-entity: billing_payment_methods x-gtm-operation: delete x-gtm-envelope: delete_simple x-gtm-availability: ga x-gtm-dangerous: true x-gtm-mass-action: false x-gtm-step-eligible: false x-gtm-schedule-required: false x-gtm-tool-class: typical components: schemas: McpError: type: object properties: success: type: boolean enum: - false error: type: object properties: code: type: string enum: - validation_failed - nothing_to_update - not_found - relation_not_found - invalid_transition - limit_exceeded - payment_required - duplicate_rejected - conflict - delete_blocked - unauthorized - forbidden - rate_limited - internal_error - service_unavailable - not_implemented message: type: string recoverable: type: boolean suggestion: type: string field_errors: type: object additionalProperties: type: array items: type: object properties: rule: type: string message: type: string required: - rule - message blockers: type: array items: type: object properties: type: type: string description: Machine-readable blocker type (active_flow, pending_tasks, …). severity: type: string enum: - hard - soft description: hard = external action required; soft = acknowledge is enough. description: type: string entity_sid: type: - string - 'null' count: type: integer resolution: type: string description: 'Hard: tool name to call. Soft: code for acknowledge[].' resolution_hint: type: string required: - type - severity - description - entity_sid - resolution - resolution_hint context: type: object additionalProperties: {} required: - code - message - recoverable meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends. actor_type: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms required: - success - error ListBillingPaymentMethodsResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - search items: type: array items: type: object properties: item: type: object properties: sid: type: string type: type: string enum: - card - paypal - apple_pay - google_pay - other card_brand: type: - string - 'null' card_last4: type: - string - 'null' card_expiry: type: - string - 'null' is_default: type: boolean origin: type: - string - 'null' saved_at: type: - string - 'null' required: - sid - type - card_brand - card_last4 - card_expiry - is_default - origin - saved_at included: type: object additionalProperties: {} required: - item - included pagination: type: object properties: next_cursor: type: - string - 'null' has_more: type: boolean total_count: type: - integer - 'null' required: - next_cursor - has_more - total_count applied_filters: type: object additionalProperties: {} includes: type: array items: type: string meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends. actor_type: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms counts: type: object additionalProperties: {} required: - success - operation - items - pagination - applied_filters - includes - meta GetBillingPaymentMethodAddLinkResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - action action: type: string description: kebab-case verb; matches the route segment. item: {} result: type: object properties: add_link: type: - string - 'null' expires_at: type: string subscription_sid: type: string required: - add_link - expires_at - subscription_sid meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends. actor_type: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms required: - success - operation - action - item - result - meta DeleteBillingPaymentMethodResponse: type: object properties: success: type: boolean enum: - true operation: type: string enum: - delete item: type: object additionalProperties: {} already_deleted: type: boolean soft_deleted: type: boolean retained: type: array items: type: string meta: type: object properties: trace_id: type: string description: UUID v7; same 128-bit value as the X-Trace-Id header. span_id: type: string pattern: ^[0-9a-f]{16}$ description: 16 hex chars, root span of this request. timestamp: type: string description: ISO 8601 UTC (Y-m-dTH:i:sZ), response time. duration_ms: type: integer minimum: 0 description: Server-side wall clock. team_sid: type: - string - 'null' description: The team this call ran in (the token team, or the team_sid override). Null when unauthenticated; absent from pre-2026-08-20 backends. actor_type: type: - string - 'null' description: user | agent | api_key | system. Null when unauthenticated; absent from pre-2026-08-20 backends. required: - trace_id - span_id - timestamp - duration_ms required: - success - operation - item - already_deleted - soft_deleted - retained - meta responses: McpServerError: description: MCP error envelope with `error.code` internal_error or service_unavailable. content: application/json: schema: $ref: '#/components/schemas/McpError' McpClientError: description: MCP error envelope. `error.code` is one of validation_failed, nothing_to_update, not_found, relation_not_found, invalid_transition, limit_exceeded, payment_required, duplicate_rejected, conflict, delete_blocked, unauthorized, forbidden, rate_limited, not_implemented. content: application/json: schema: $ref: '#/components/schemas/McpError' securitySchemes: BearerJwt: type: http scheme: bearer bearerFormat: JWT description: Access token issued by gtm.service.id. Its `access_identity` claim carries `team_sid`, `actor_sid` and `actor_type`, and that team scope is authoritative. TeamSid: type: apiKey in: header name: Team-SID description: Team scope for tokens that do not carry one. Ignored when the token already names a team.