Paydirt iOS SDK

Voice AI feedback for subscription apps

Developer and agent resources

Start with the human guide here, or use the machine-readable contracts directly. The OpenAPI document describes every HTTP operation and structured error. MCP discovery identifies the authenticated remote server without exposing its tools.

Authentication

Paydirt separates account authority, installed-app submission, Slack authorization, and MCP authorization. Never place an account Bearer token or Slack token in an iOS app.

Account API

Dashboard, form-management, response-reading, summary, and analysis routes use Authorization: Bearer <token>. The browser obtains the short-lived account context through Google authorization.

Installed iOS SDK

Form loading, conversation, audio, response submission, and delivery receipts use the app-specific public X-API-Key. When bundle enforcement is enabled they also require X-Paydirt-Bundle-ID. Rotate a leaked SDK key from app settings.

Remote MCP

The public MCP discovery document points to https://mcp.paydirt.ai/mcp. The execution endpoint requires OAuth with PKCE and publishes protected-resource metadata. Public discovery does not grant tool access.

Slack

Slack uses its own OAuth installation. Paydirt stores the bot credential server-side, lets you choose channels in your workspace, and never returns that credential to the SDK or an agent.

Every JSON error includes a stable code, human message, actionable resolution, and request_id. See the complete schemas and security requirements.

Subscription analytics boundary

Use RevenueCat or the App Store for revenue, MRR, entitlement, transaction, and renewal totals. Use Paydirt to retrieve exact cancellation conversations and their submitted subscription context, explain changes in churn reasons, separate trial from paid cancellations, and produce read-only recurring feedback totals and highlights. Paydirt does not infer financial metrics that the connected billing source has not supplied.

Recommended

Install with a Coding Agent

Connect Paydirt to your coding agent once, then ask for it in plain language. Your agent opens one browser tab for Google sign-in and approval; everything else happens in chat. It recommends Subscription Cancellation, Trial Cancellation, and Suggest a Feature, confirms the plan with you, installs the SDK, writes the key into your project, and launches your app so you can try the real form. No API keys are pasted by hand.

Claude Code: claude mcp add --transport http paydirt https://mcp.paydirt.ai/mcp

Codex: codex mcp add paydirt --url https://mcp.paydirt.ai/mcp

Claude Code plugin: /plugin marketplace add Paydirt-AI/paydirt-mcp then /plugin install paydirt@paydirt-plugins

Then ask:

Add Paydirt to this app. Set up cancellation feedback and Suggest a Feature.

Fallback for hosts without remote MCP support: codex mcp add paydirt -- npx -y paydirt-mcp@latest or claude mcp add paydirt -- npx -y paydirt-mcp@latest. The agent can also follow the machine-readable installation contract itself.

Installation

Add Paydirt to your iOS app using Swift Package Manager:

Package URL:

https://github.com/Paydirt-AI/paydirt-ios

Option 1: In Xcode

  1. File → Add Package Dependencies
  2. Paste the URL above
  3. Click Add Package

Option 2: In Package.swift

dependencies: [
    .package(url: "https://github.com/Paydirt-AI/paydirt-ios", from: "2.2.0")
]

Requirements

  • iOS 15.0+
  • Swift 5.9+
  • Xcode 15+

Info.plist

Add microphone permission for voice feedback:

<key>NSMicrophoneUsageDescription</key>
<string>Used to record voice feedback</string>

Quick Start

Initialize Paydirt in your app:

import Paydirt

// In your App init or AppDelegate
Paydirt.configure(apiKey: "your_api_key", theme: .automatic)

// Optional native StoreKit cancellation detection
Paydirt.enableStoreKitIntegration(
    productIds: ["pro.monthly", "pro.yearly"],
    cancellationFormId: "subscription-cancellation-form-id",
    trialCancellationFormId: "trial-cancellation-form-id"
)

Subscription Integrations

Paydirt supports native StoreKit, RevenueCat, Superwall, and app-owned cancellation events. Trial and paid cancellations route to separate forms.

The Paydirt core has no RevenueCat or Superwall package dependency, so it does not disturb the app's existing purchase packages or versions. The coding agent installs the required integration automatically.

An older RevenueCat version is not a blocker. The agent keeps it and adapts the small integration source to the APIs already compiling in the app; it does not upgrade RevenueCat solely for Paydirt.

import Paydirt

Paydirt.configure(apiKey: "your-paydirt-key", theme: .automatic)
Paydirt.enableStoreKitIntegration(
    productIds: ["pro.monthly", "pro.yearly"],
    cancellationFormId: "subscription-cancellation-form-id",
    trialCancellationFormId: "trial-cancellation-form-id"
)

// In RevenueCat apps, the installer adds compatibility source and calls:
Paydirt.enableRevenueCatIntegration(
    cancellationFormId: "subscription-cancellation-form-id",
    trialCancellationFormId: "trial-cancellation-form-id"
)

Manual Form Display

Show a form from any button, screen, or successful in-app action:

// Present a specific form by ID
Paydirt.shared.presentForm(
    formId: "your-form-id",
    userId: "user-123",           // optional
    metadata: ["paydirt_placement": "after_successful_export"],
    onCompletion: { completed in
        print("Form completed: \(completed)")
    }
)

You can ask your coding agent: “Add a feedback form titled Export Feedback after a successful export.” It creates or reuses the form, edits that exact placement, assigns Slack, builds, and returns a test path.

Structured Results

Use the optional submission callback when your app needs the response ID, transcript, and metadata for an agent or internal workflow.

Paydirt.presentForm(
    formId: "your-form-id",
    userId: "user-123",
    metadata: ["plan": "pro"],
    onSubmission: { result in
        print(result.responseId)
        print(result.messages)
    },
    onCompletion: { completed in
        print("Completed: \(completed)")
    }
)

Paydirt saves an encrypted snapshot after every accepted turn. A stable response ID and monotonic snapshot version prevent duplicate responses and stale retries.

Privacy and Reliability

  • Voice recording requires an explicit disclosure before capture.
  • Recordings stop after two minutes and use a protected temporary file.
  • Local recordings are deleted after transcription succeeds or fails.
  • Pending feedback is encrypted with a Keychain-backed key.
  • Retry delivery is idempotent and reuses the same response ID.
  • Paydirt 2.2.0 bundles its own Apple privacy manifest.
  • Agent-created apps bind their public SDK key to the discovered bundle ID.

Presentation

Paydirt follows the system appearance by default. Use a preset or pass a custom PaydirtTheme to match your app.

Paydirt.configure(apiKey: "your-api-key", theme: .automatic)

// Or choose a fixed preset at runtime
Paydirt.setTheme(.dark)

let formView = Paydirt.showForm(
    formId: "your-form-id",
    userId: "user-123"
)

Get Your API Key

  1. Sign up at paydirt.ai
  2. Create an app in the dashboard
  3. Copy your API key from App Settings
  4. Create a cancellation form

Features

  • Voice feedback - Users can speak their feedback
  • AI follow-ups - Intelligent conversational questions
  • Subscription integrations - Native StoreKit, RevenueCat, Superwall, and custom events
  • Agent-controlled placement - Add a named form to a button, screen, action, or custom condition
  • Slack notifications - Get feedback in real-time
  • Durable turns - Encrypted local and remote snapshots after every accepted answer
  • Raw Slack delivery - One final message with every Q/A and optional summary at the bottom
  • Remote form control - Enable/disable forms without app updates