Skip to main content

Practifi Setup

Configuring a custom OAuth app in your Practifi org for use with Caddi

Practifi runs on Salesforce, so connecting Caddi means creating an OAuth app inside your own Practifi org. Every step happens in Salesforce Setup — Practifi itself publishes no separate API.

Salesforce disabled creation of new legacy Connected Apps in the Spring '26 release. The New Connected App button is greyed out, and this applies through the UI, the API, and the Metadata API. Existing connected apps keep working.

Use External Client Apps instead — that's what this guide covers. If you find older instructions pointing at Connected Apps, they're out of date.

Before you start

You'll need:

  • Salesforce System Administrator in your Practifi org, or a user with Customize Application and Manage Connected Apps

  • The API Enabled permission on the user who will connect

  • Owner or Admin access to your Caddi organization

  • To know whether you're connecting a production or sandbox org — they need separate apps

Practifi orgs are often provisioned on Salesforce Platform-family licenses. Confirm the connecting user's license actually includes API access before you start, or the connection will fail for reasons that look unrelated.

Step 1: Create the External Client App

Sign in to your Practifi org as an administrator.

  1. Click the gear icon and open Setup.

  2. In Quick Find, search for App Manager and open it.

  3. Click New External Client App.

  4. Fill in Basic Information:

    • NameCaddi Auth

    • API Name — Salesforce generates this for you

    • Contact Email — your IT or operations contact

    • Distribution StateLocal

    • Info URLhttps://trycaddi.com

  5. Expand API (Enable OAuth Settings) and tick Enable OAuth.

  6. Callback URL — enter https://app.trycaddi.com/oauth-callback. Multiple URLs are allowed, one per line.

  7. OAuth Scopes — move these into the Selected column:

    • Manage user data via APIs (api) — the main read and write scope

    • Perform requests at any time (refresh_token, offline_access) — required, or the connection will drop

    • Access unique user identifiers (openid) and Access the identity URL service (id, profile, email, address, phone) — for sign-in

  8. Do not select Full access (full). It's broader than needed and doesn't reliably return a refresh token.

  9. Under flow and security settings:

    • Enable Authorization Code and Credentials Flow

    • Require Secret for the Web Server Flow — enabled

    • Require Secret for Refresh Token Flow — enabled

    • Require PKCE — leave enabled

  10. Click Create.

Step 2: Set the refresh token policy

Skipping this step is the most common reason a Practifi connection silently stops working weeks later.

  1. Open the app in External Client App Manager and go to the Policies tab.

  2. Click Edit.

  3. Under App Authorization, set Refresh Token Policy to Refresh token is valid until revoked.

  4. Click Save.

Step 3: Retrieve the consumer key and secret

These values are as sensitive as an administrator password. Never send them by email or chat — use a password manager if you need to share them.

  1. In External Client App Manager, open your app and go to the Settings tab.

  2. Scroll to OAuth Settings and click Consumer Key and Secret. Salesforce may ask you to verify your identity.

  3. Copy the Consumer Key and Consumer Secret.

Unlike most vendors, Salesforce lets you view these again later behind identity verification, so you don't have to store them permanently.

Step 4: Configure Practifi in Caddi

This step must be completed by a Caddi organization owner or admin.

  1. In Caddi, open Integrations in the left sidebar, then click the Integration Setup tab at the top of the page. This tab is only visible to organization owners and admins.

  2. Find Practifi in the list and click Configure.

Enter the following values:

  • Consumer Key — the Consumer Key from your External Client App

  • Consumer Secret — the Consumer Secret from the same app

  • OAuth Scopes — leave blank to inherit Caddi's defaults. If you entered a custom scope set on the app, enter the matching strings here — and refresh_token offline_access must be among them or Practifi issues no refresh token.

  • Sandbox Org — enable if this app lives in a Practifi sandbox. Sandboxes authorize through test.salesforce.com rather than login.salesforce.com.

  • Instance URL — required for sandbox orgs, for example https://mypractifi--dev2026.sandbox.my.salesforce.com. Production orgs return this automatically, so leave it blank.

Click Save Configuration. Caddi validates the credentials immediately — if something is wrong you'll see an error right away, and nothing is stored until validation passes.

Step 5: Connect your account

  1. Go back to the My Connections tab and find Practifi.

  2. Click Connect + and sign in to Practifi.

  3. On first authorization you'll see a consent screen listing what Caddi is requesting — click Allow.

  4. You'll be returned to Caddi with the connection active.

How the connection behaves

  • Each user connects their own Practifi account. The OAuth scopes bound what the app can request; the real ceiling is the connecting user's profile and permission sets. Give them read and write on the Practifi objects your loops need, and leave user-management permissions off.

  • A custom connection replaces the standard one. Members of your organization will only see the option to connect through your app.

  • Newly created apps take a few minutes to become usable. Salesforce typically needs 2–10 minutes to propagate a new consumer key. An invalid_client_id error right after creation is usually just this.

  • Sandbox and production need separate apps. Consumer keys differ per org, and a sandbox refresh can invalidate the app in that sandbox.

  • API request limits are org-wide over a rolling 24 hours and scale with license count. Practifi orgs are often small, so the daily cap can be genuinely low — check Setup → Company Information → API Requests, Last 24 Hours.

  • Revoking access. Delete the External Client App, or rotate its OAuth credentials, in Salesforce Setup.

Troubleshooting

The New Connected App button is greyed out

Expected as of Salesforce Spring '26. Use New External Client App instead — that's the path this guide follows.

invalid_client_id immediately after creating the app

Salesforce hasn't finished propagating the new credentials. Wait 10 minutes and try again before changing anything.

The connection works, then stops after a few weeks

The refresh token policy is still at its default. Set Refresh Token Policy to Refresh token is valid until revoked on the app's Policies tab.

Server-to-server calls are blocked but browser sign-in works

Login IP Ranges on the connecting user's profile are restricting access. Relax them for the app or add Caddi's egress addresses — contact Caddi support for the current list.

Loops fail late in the day with API limit errors

Your org's 24-hour API request allowance is exhausted. Check Setup → Company Information, then reduce loop frequency or ask Salesforce about additional capacity.

A sandbox connection fails to authorize

Enable the Sandbox Org toggle and supply the sandbox Instance URL. Without both, Caddi authorizes against the production login host.

Still stuck? Contact Caddi support with the exact error message you're seeing and the time it occurred.

Automation ideas

RIAs

Client meeting → Practifi record update

Caddi pulls the meeting summary and updates the Practifi client record with topics discussed, next steps, and follow-up dates.

Onboarding request → workflow kickoff

Caddi creates the Practifi entity and relationships from an onboarding form and starts the process with the right tasks assigned.

Document received → filed and logged

Caddi files incoming client documents, logs the activity against the Practifi record, and closes the outstanding item.

Service review cycle → advisor prep

Ahead of scheduled reviews, Caddi assembles each client's Practifi activity, outstanding items, and portfolio position into a briefing for the advisor.

Did this answer your question?