From merge-unified
Guide an AI coding agent through the full Merge Link implementation flow — context loading, database setup, backend API endpoints, and frontend UI. Use when starting a Merge integration, implementing Merge Link in a new project, setting up linked_accounts, or building the connect button or app marketplace UI.
How this skill is triggered — by the user, by Claude, or both
Slash command
/merge-unified:implementing-linkThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Merge Link is a pre-built modal that handles OAuth and third-party authentication on behalf of your users — developers don't build the auth UI themselves. This skill guides you through the full implementation flow: loading context, setting up the database, building the backend API, and wiring up the frontend.
Merge Link is a pre-built modal that handles OAuth and third-party authentication on behalf of your users — developers don't build the auth UI themselves. This skill guides you through the full implementation flow: loading context, setting up the database, building the backend API, and wiring up the frontend.
I'm the implementing-link skill. I'll guide you through connecting your application to Merge Link — database schema, backend endpoints, and the frontend UI. Are you building a single connect button, or an app marketplace where users browse integrations?
MERGE_API_KEY)Work through these steps in order. Steps 2–4 invoke focused sub-skills; Step 1 runs inline.
Do not write any code in this step. Read the reference docs first, then scan the codebase, then confirm readiness.
1a. Read all three reference docs:
references/platform-overview.md — Core Merge concepts, auth flow, account lifecyclereferences/backend-implementation.md — Backend API patterns, token exchange, database schemareferences/frontend-implementation.md — Frontend UI patterns (Connect Button and Marketplace)Read each file completely before proceeding.
1b. Scan the codebase. Ask the user first:
"I'll search your codebase for your tech stack, existing schema, and any Merge-related code. Ready to proceed?"
Then identify:
merge, MERGE_API_KEY, account_token)@mergeapi/merge-node-client (package.json), MergePythonClient (requirements.txt / pyproject.toml), dev.merge:merge-java-client (pom.xml / build.gradle), merge-go-client (go.mod), merge_ruby_client (Gemfile), Merge.Client (.csproj). Record yes/no and which language.@mergeapi/react-merge-link in package.json. Record yes/no (or N/A if not React).employees, candidates, contacts, deals), route names, model names, or README/CLAUDE.md references to HR, recruiting, CRM, ticketing, etc. Record what you find or unknown.organizations, companies, tenants, accounts, workspaces. Record the table name and its primary key column, or not found.1c. Confirm readiness with a brief summary:
unknown{table}.{pk} or not found1d. Ask all unresolved questions in one message before proceeding to Step 2:
Before I start building, I have a few quick questions:
Categories: Based on your codebase I believe you're implementing [inferred list, or "—"]. Which Merge categories are you implementing? (
hris,ats,crm,accounting,ticketing,filestorage,knowledgebase)Linked Account strategy — at the Merge API level,
end_user_origin_id+categorydetermines uniqueness:
- Strategy 1: Use a stable per-org identifier as
end_user_origin_id(e.g. a GUID on your org record). Each org can have 1 Linked Account per category (one HRIS, one ATS, etc.).- Strategy 2: Generate a new GUID per connection as
end_user_origin_id. Each org can have multiple Linked Accounts per category (e.g. two different HRIS systems). Which do you need?Backend SDK preference: [If not installed:] Would you prefer the official Merge SDK (recommended — handles types and retries) or raw HTTP? [If already installed:] I see the Merge SDK is in your dependencies — I'll use it unless you prefer raw HTTP.
Organization table: [If found:] I found
{table}as your org/tenant table — I'll FKlinked_accounts.organization_idto{table}.{pk}. Is that correct? [If not found:] What is the table or model that represents a customer organization or tenant in your system?Frontend SDK (React projects only): [If
@mergeapi/react-merge-linknot installed:] Would you prefer the React Merge Link SDK (@mergeapi/react-merge-link, recommended — uses theuseMergeLinkhook) or CDN+vanilla JS? [If already installed:] I see@mergeapi/react-merge-linkin your dependencies — I'll use it unless you prefer the CDN approach. [If not React:] Skipped.
Record the user's answers. Carry them as context into all sub-skills (Steps 2–4).
link-setup-databaseCreates the linked_accounts table (and any other required tables) to store Merge account tokens and connection metadata.
link-implement-backendBuilds the server-side endpoints: generating Link tokens, exchanging public tokens for account tokens, and storing them.
link-implement-frontend-connect
Adds a single "Connect" button that opens the Merge Link modal.link-implement-frontend-marketplace
Builds an integration marketplace UI where users browse and connect multiple integrations.Choose one OR the other based on your product's UX.
Before invoking the Marketplace skill (4b only): Scan the frontend for an existing integrations page, marketplace, or app catalog. Look for files or routes named marketplace, integrations, app-center, catalog, or similar.
If you chose the Connect Button (4a), skip the pre-scan and invoke link-implement-frontend-connect directly.
Always complete Step 1 (load context) before starting Step 2.
SYMPTOM: link_token request returns 401
CAUSE: API key is missing or belongs to the wrong Merge environment (production key used in sandbox)
FIX: Set Authorization: Bearer {your-test-api-key} and confirm the key is from https://app.merge.dev → Settings → API Keys → Test environment
SYMPTOM: exchange_public_token returns 400 "token expired"
CAUSE: The public token from Merge Link is single-use and has a short TTL (~10 min). Either it was already exchanged once, or /exchange was deferred (e.g., to a background job) and the window passed.
FIX: Call exchange immediately after onSuccess fires; never store or reuse a public token
SYMPTOM: linked_accounts table has duplicate rows for the same user
CAUSE: Missing unique constraint on (organization_id, end_user_origin_id) or upsert not used on exchange
FIX: Add UNIQUE(organization_id, end_user_origin_id) and use INSERT ... ON CONFLICT DO UPDATE
SYMPTOM: Merge Link modal does not open
CAUSE: Merge Link wasn't loaded before invocation. For React, @mergeapi/react-merge-link (npm) wasn't installed or imported. For vanilla JS, the CDN script https://cdn.merge.dev/initialize.js wasn't loaded yet, or MergeLink.initialize was called before DOM ready.
FIX: React: npm install @mergeapi/react-merge-link and use the useMergeLink hook (see /merge-unified:onboarding Step 4 for the full setup). Vanilla JS: include <script src="https://cdn.merge.dev/initialize.js"></script> in <head> and call MergeLink.initialize inside a DOMContentLoaded listener.
SYMPTOM: account_token is null after successful Link flow
CAUSE: The exchange endpoint was never called — only link_token was created
FIX: Ensure your onSuccess callback POSTs to your backend's /api/merge/exchange-public-token route
npx claudepluginhub merge-api/merge-unified-skills --plugin merge-unifiedCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.