Skip to content
KudosCRM

Referral partners: earn up to 30%. Become a referral partner

Help · Developers and apps

Build an app and list it in the KudosCRM Marketplace

Turn your product into a KudosCRM app that any workspace can install. Become a developer from a free workspace, accept the partner agreement, create the app, set up OAuth, scopes, webhooks and the listing, test it, send it to review and release it to the Marketplace. Every screen, limit, endpoint and error, in order.

Updated October 2026

Any KudosCRM workspace admin can build an app that other KudosCRM workspaces install. You become a developer from your own workspace, build the app in the developer console at app.kudoscrm.com/developers, and send it to KudosCRM for review. Once KudosCRM approves it, you release it, and it appears in the Marketplace of every KudosCRM workspace. Becoming a developer and listing an app are free.

This guide follows a developer from the first click to a listed app. The examples use a made-up company, Acme Telecom, and its app, Acme Dialer, on example.com domains.

Watch the video

Video cover: Build an app for KudosCRM, and list it in the Marketplace. Step by step, 9 minutes. Beside the title, the Marketplace listing of the sample app Acme Dialer with its Install button, marked Live in the Marketplace, and a call it logged on a KudosCRM contact.
The same steps as this guide, recorded in the real developer console (9 min). Watch on YouTube.

Chapters: 0:24 Create your account · 1:16 Become a developer · 2:24 Create your app · 3:46 Scopes and a test install · 5:09 Events, listing and submit · 6:34 Release it · 7:22 A customer installs it · 8:23 Where to go next.

At a glance

QuestionAnswer
Who can buildAny admin of a KudosCRM workspace. The free plan is enough.
CostFree. Becoming a developer is free, and listing an app in the Marketplace is free.
Where you buildThe developer console: https://app.kudoscrm.com/developers
The steps1 Become a developer · 2 Accept the partner agreement · 3 Create the app · 4 Fill in the editor tabs · 5 Install it in your own workspaces and test · 6 Submit for review · 7 Release
How installs workOAuth 2.0 authorization code with PKCE (S256). The customer's admin approves your app on a consent screen.
How you get eventsSigned webhooks (Standard Webhooks headers), with a signing key for each install.
Starter limits5 apps and 5 test workspaces until KudosCRM approves your first app. Removed test workspaces still count.
ReviewKudosCRM reviews every app and every new version before it is listed. The console says review usually takes up to 5 business days.
Where a listed app appearsSettings › Marketplace in every KudosCRM workspace, its own listing page, and kudoscrm.com/integrations after the next website build.
Developer docshttps://app.kudoscrm.com/docs/build-an-app/

What you can build

An app is your product, connected to KudosCRM. A customer's admin installs it into their workspace, and from then on your app can read and write that workspace's data within the access the admin approved. Examples: a phone system that logs calls on the right contact, a billing tool that keeps companies in sync, or a booking tool that adds meetings to the timeline.

The console's sign-up page lists what every developer gets:

  • OAuth 2.0 installs: workspaces install your app through a consent screen their admin reads and approves.
  • Signed webhooks: CRM events delivered to your server, signed with a key for each install.
  • REST API: contacts, companies, deals, activities and more, within the scopes each install grants.
  • A marketplace listing: in every workspace's marketplace and on kudoscrm.com, once KudosCRM approves your app.

Building a calling or SMS app? Pick the Telephony v1 contract. KudosCRM then turns your call events into call activities, missed-call tasks and voicemails with no custom code on either side.

Only need your own workspace?
If only your own workspace will use what you build, you don't need an app. An API token and an outbound webhook are simpler. See API tokens and the REST API. An app is for a product that many workspaces install.

Who can be a developer

  • Any admin of a KudosCRM workspace. The free plan is enough. That workspace becomes your company's developer workspace (the docs call it the home workspace). You build and test from it.
  • One workspace, one company. A workspace can be the developer workspace of only one company. To build as another company, use that company's own workspace.
  • Your team. Every admin of the developer workspace who has the Build, submit & release developer apps permission is a developer of your company. Admins have it by default. They appear in the console under Team.
  • Members who are not admins can't set this up. They see “An admin of this workspace can set this up”.

If you don't have a KudosCRM account yet

  1. Open the developer console
    On kudoscrm.com/integrations, find Build an App for the KudosCRM Marketplace and click Start Building. Or go straight to https://app.kudoscrm.com/developers. If you are signed out, KudosCRM shows the sign-in page and remembers that you were going to the developer console.
  2. Create an account
    On the sign-in page, click Create an account (next to “New here?”). On Create your account, enter your first name, last name, work email and a password, tick the terms box, and click Create account. You can also click Sign up with Google.
  3. Verify your email
    On Verify your email, enter the 6-digit code KudosCRM emailed you. It expires in 15 minutes. Click Verify email. Until you verify, your workspace is view-only, so verify before you continue.
  4. Land on the developer console
    After verifying, you land back on /developers, on the page Build apps for KudosCRM. Continue with the next section.
The KudosCRM sign-in page, reached from the developer console while signed out. At the top right is the line New here? followed by a Create an account link. The page is headed Welcome back, with the line Sign in to pick up where your team left off. Below are a Continue with Google button, OR, an Email address field, a Password field with a Forgot password? link and a Show button, a ticked Keep me signed in on this device box, a Sign in button, and an Email me a sign-in link instead link.
Signed out, the console sends you to sign in first. New here? Click Create an account.

Become a developer

  1. Open the developer console from your company's workspace
    Sign in and switch to the workspace your company will build from. Go to https://app.kudoscrm.com/developers. The page is titled Build apps for KudosCRM, with four cards under What you get and a box called Become a developer.
  2. Enter your company name
    In Company name, type your company's name, for example Acme Telecom. It is shown on your listings as the app's developer. Up to 80 characters.
  3. Enter your website
    In Website, type your company's site, for example https://www.example.com. If you type only a domain, KudosCRM adds https://. Your company claims this site's domain (www.example.com claims example.com). Your app's redirect URLs, install page, app URL and help article URL must sit on that domain or a host under it. KudosCRM verifies the domain during review.
  4. Enter your support email
    In Support email, type where customers write for help with your apps, for example [email protected].
  5. Read the three notes
    Under the fields, the box says: new publishers can have up to 5 apps and 5 test workspaces until KudosCRM approves their first app; every app and every version is reviewed before it's listed, and until then it installs only in your own workspaces; and you'll accept the partner agreement before your first submission for review.
  6. Click Become a developer
    A message confirms “Acme Telecom is set up — Create your first app to get started.” The console opens on My apps.
The Build apps for KudosCRM page, subtitled Anyone with a KudosCRM workspace can build an app. KudosCRM reviews every app before it's listed. Under What you get are four cards: OAuth 2.0 installs, Signed webhooks, REST API and A marketplace listing, each with one sentence. Below, the Become a developer box says Acme Telecom becomes your company's developer workspace. You build and test from here. It has three required fields, each with a hint: Company name (Acme Telecom; shown on your listings as the app's developer), Website (https://www.example.com; your company claims this site's domain for your app's URLs, and KudosCRM verifies it during review) and Support email (support@example.com; where customers write for help with your apps). Three notes follow: up to 5 apps and 5 test workspaces until KudosCRM approves your first app; every app and version is reviewed before it's listed and until then installs only in your own workspaces; you'll accept the partner agreement before your first submission. Buttons: Become a developer and Read the docs.
Three fields make your workspace a developer workspace.

My apps is the console's home. The left menu has My apps, Analytics, Test workspaces, Logs, Team and Partner agreement. Under the menu, a card shows your company and whether its domain is verified yet. A line under the first box counts your apps against the starter limit, for example “0 of 5 apps while KudosCRM hasn't approved your first app yet. The limit lifts with that approval.”

The My apps page of the developer console for a new developer. The top bar shows Acme Telecom · partner. The left menu lists My apps, Analytics, Test workspaces, Logs, Team and Partner agreement, and under it a card reads Acme Telecom, example.com, Domain not verified yet · 1 team member. The main area shows Create your first app with a Create app button, then the line 0 of 5 apps while KudosCRM hasn't approved your first app yet. The limit lifts with that approval. Next is an Accept the partner agreement box (You need it before you submit your first app for review) with a Read the agreement button, a Test workspaces card with a New button and no workspaces yet, a Program card, and Start a new app in five steps: Create the app, Pick scopes, Subscribe to events, Install in a test workspace, Submit for review.
My apps right after sign-up: create an app, and accept the partner agreement before your first submission.

When Become a developer is refused

What you seeWhat it meansWhat to do
“An admin of this workspace can set this up”You are a member, not an admin, of this workspace.Ask an admin to become a developer here, or to make you an admin.
“{Workspace} is already a developer workspace”Someone already made this workspace a developer workspace.Ask an owner of the workspace for developer access (admin role).
“Your apps are in another workspace” or “You build apps in another workspace”, with Switch to {name}You are already a developer in another workspace.Click Switch to {name}. If the form also shows, you may make this workspace a second company's developer workspace.
“Partner access is by invitation”KudosCRM has paused open sign-up for now.Click Request access to email KudosCRM, which can invite your company.
“Support can't do this for the customer”Someone from support is signed in as you.Sign in as yourself and try again.
“That's KudosCRM's own name. Enter your company's name.”Names that read as KudosCRM or Saanverse are reserved.Use your own company's name. “Kudos Bakery” is fine.
“That's a KudosCRM website. Enter your company's own website.” / “That's a KudosCRM address…”The website or support email is on a KudosCRM domain.Use your company's own website and email.
“{domain} is verified for another KudosCRM publisher. Enter your own company's website.”Another company already verified that domain.Enter your own company's website. If the domain is yours, contact KudosCRM support.

Accept the partner agreement

The partner agreement is the contract between your company and Kudos for apps in the Marketplace. It is a clickwrap: you read it in the console and tick a box. You can build without it, but Submit stays blocked until your company has accepted the version in force. When Kudos publishes a new version, your company accepts it again before its next submission.

  1. Open the agreement
    Click Partner agreement in the left menu, or Read the agreement on My apps. The page is titled Partner agreement. Under the agreement's title you see its version and date, for example “Version 2026-10”, and a Download PDF link when one is available.
  2. Read it, then tick the box
    Tick “I have read and agree to the KudosCRM Partner Agreement on behalf of Acme Telecom”.
  3. Click Accept
    A message confirms “Partner agreement accepted — You can send apps to review now.” The page then shows who accepted it, when, and which version.
The Partner agreement page, with Partner agreement highlighted in the left menu. Its subtitle reads Accepted once for Acme Telecom, and again when KudosCRM publishes a new version. A card shows the title KudosCRM Partner Agreement with a Draft — for review pill and the line Version 2026-10 · 01 Oct 2026, then the agreement text: the opening paragraph and the heading 1. The program, a marker where the middle of the agreement is left out of this picture, and the last two clauses, 11.2 and 11.3. At the bottom of the card is an unticked checkbox reading I have read and agree to the KudosCRM Partner Agreement on behalf of Acme Telecom, and an Accept button that stays greyed out until the box is ticked.
Accept once per company, and again for each new version.
  • If the text changed while the page was open, KudosCRM says “The Partner Agreement changed while this page was open. Read the new version above, then accept it.” Tick the box again and click Accept.
  • When a new version is published, a banner says “A new version of the Partner Agreement needs your acceptance before your next submission.”

Create an app

  1. Click Create app
    On My apps, click Create app. The page Create an app asks for a name, a key and a category.
  2. Name it
    In Name, type the name customers will see on the Marketplace card and listing page, for example Acme Dialer. You can change it later. Up to 80 characters.
  3. Choose the key, carefully
    KudosCRM suggests a Key from the name, for example acme_dialer. The key is permanent. It becomes your client id (app_acme_dialer) and the name your records carry in KudosCRM. Use 2–60 lowercase letters, digits or underscores, starting with a letter. Put your company's name in it. Built-in app keys and well-known brand names are reserved (for example slack, salesforce, hubspot, zoho, pipedrive, google, microsoft, whatsapp, meta, twilio, stripe, zoom, calendly, mailchimp), and so is any key starting with kudos.
  4. Pick a category
    Open Category and pick one, for example Calling & SMS, Email & calendar, Messaging & chat, Meetings & video, Payments & billing, Automation, Ads & analytics or Data & migration.
  5. Click Create app and store both secrets now
    The page changes to “Acme Dialer is created”. It shows the client id and says the app starts as a private draft, version 1.0, that installs only in your company's workspace. It shows two secrets once: the Client secret (starts kcs_; your server sends it with the client id to exchange codes and refresh tokens) and the Signing secret (starts whsec_; each install's webhook key is derived from it). Copy both into your server's secret settings.
  6. Confirm and open the app
    Tick “I have stored both secrets. I understand they can't be shown again.” and click Open Acme Dialer. The app editor opens on its Auth tab.

The secrets are shown once
KudosCRM keeps only a fingerprint of each secret. If you lose one, rotate it from the app's Auth tab to get a new one. If you try to leave the page before storing them, KudosCRM asks “Leave before storing the secrets?”.

The Create an app page (A name, a key and a category. You can change everything but the key later.) after clicking Create app. A card reads Acme Dialer is created. Its client id is app_acme_dialer. It starts as a private draft, version 1.0, that installs only in Acme Telecom's workspace. A yellow warning says These two secrets are shown once. Copy them into your server now — KudosCRM keeps only a fingerprint and can't show them again. You can rotate either one later. Two masked fields follow, each with a show (eye) button and a copy button: Client secret (Your server sends it with the client id to exchange codes and refresh tokens) and Signing secret (Each install's webhook key is derived from it — for verifying the events you receive and signing the ones you send). Below, an unticked checkbox reads I have stored both secrets. I understand they can't be shown again., and a button reads Open Acme Dialer.
Copy the client secret and the signing secret before you leave this screen.

Fill in the app editor, tab by tab

The editor has seven tabs down the left: Basic info, Auth, Scopes, Events, Listing, Test and Submit. Each tab shows a green check when it has everything review needs, or “N to do” while it doesn't. The button at the top right shows what is left: Finish setup (N) takes you to the next tab with something to do, and becomes Submit v1.0 when nothing is left. Beside it, a short line shows the state of the automated checks, for example “Checks not run yet” or “4 of 6 checks pass”.

Everything you fill in here is the app's working copy: the version KudosCRM reviews. When you change a field, a bar at the bottom says “Unsaved edits on …”. Click Save to keep them, or Undo edits.

Basic info

  • Name: the name on the Marketplace card and listing page.
  • Publisher: your company. It can't be changed here.
  • Category: where the app sits in the Marketplace.
  • Website, Privacy policy URL and Terms of service URL: all three are needed to submit. Use full https:// URLs.
  • Support email: needed to submit unless you give a help article URL. Reviewers check that it reaches a person.
  • Support response time: optional, for example “Replies within 1 business day”. Shown on the listing's Support tab.
  • Help article URL, App URL (where “Open Acme Dialer” goes from an installed app) and Install URL (where the Marketplace's Install button sends admins to start the connection). These three must be on your domain or a host under it, for example https://app.example.com/integrations/kudos/install. The line above them says so: “Help article, app and install URLs must be on example.com or a host under it. KudosCRM verifies your domain during review; until then your app can't be listed.”
  • More options › Internal name (optional): a name only you and reviewers see. Leave it empty to use the name above.
The app editor for Acme Dialer, with a Draft v1.0 pill and the line app_acme_dialer · created 29 Oct 2026 under the name, and Analytics and Finish setup (5) buttons at the top right. The tab list on the left shows Basic info (green check), Auth (1 to do), Scopes (1 to do), Events (green check), Listing (3 to do), Test and Submit. The Basic info form shows Name (Acme Dialer), Publisher (Acme Telecom, locked: Your company, as you registered it), Category (Calling & SMS), Website (https://www.example.com), Support email (support@example.com), Privacy policy URL, Terms of service URL, and Support response time (Replies within 1 business day; shown on the listing's Support tab). A line then says help article, app and install URLs must be on example.com or a host under it, and that until KudosCRM verifies the domain the app can't be listed. Below are Help article URL (https://help.example.com/kudoscrm), App URL (https://app.example.com; where Open Acme Dialer goes from an installed app) and Install URL (an app.example.com/integrations address; Install on the marketplace sends admins here to start the connection), and a More options link.
Basic info: names, links and where installs start.

Auth

  1. Check your client credentials
    The Client credentials card shows the Client ID (with a copy button), and the Client secret and Signing secret masked, each with a Rotate button. The client secret shows its kcs_ start and its last four characters, so you can tell which one your server holds; the signing secret shows whsec_. “Secrets are shown once, when they are created or rotated. KudosCRM keeps only a fingerprint.”
  2. Rotate a secret if you lost it or it leaked
    Click Rotate beside the secret. Under “Keep the old one working for”, choose Stop it now, 1 hour or 24 hours. During that time both the old and the new secret work, so you can deploy the new one without dropping a request. The new secret is shown once. Every developer on your team gets an email when a secret is rotated.
  3. Add your redirect URL
    Under Redirect URLs, click Add URL and enter the URL on your server that receives the authorization code, for example https://app.example.com/integrations/kudos/callback. It must use https:// and sit on your domain or a host under it. You can add up to 10. The authorize step sends people back only to a URL on this list. Each URL in the list has a pill: Domain not verified until KudosCRM verifies your domain (it doesn't stop you saving or submitting), then Verified domain.
  4. Use “Test workspaces only” for local development
    Tick Test workspaces only to add a URL on another host, such as http://localhost:3000/callback or http://127.0.0.1. Such a URL works only when installing in your company's workspace and your test workspaces. Its pill reads Test workspaces only.
  5. Copy the endpoints
    The Endpoints card lists the authorize (GET https://app.kudoscrm.com/oauth/authorize), token (POST https://api.kudoscrm.com/oauth/token) and revoke (POST https://api.kudoscrm.com/oauth/revoke) URLs, each with a copy button, and says: “Standard OAuth 2.0 authorization code with PKCE (S256). Access tokens last 1 hour; refresh tokens rotate on every use, so most OAuth client libraries work unchanged.”
The Auth tab of the Acme Dialer editor, with Finish setup (4) at the top right and green checks on Basic info, Auth and Events. The Client credentials card shows the Client ID app_acme_dialer with a copy button, the Client secret masked as kcs_ followed by dots and its last four characters, and the Signing secret masked as whsec_ followed by dots, each secret with a Rotate button, and the line Secrets are shown once, when they are created or rotated. KudosCRM keeps only a fingerprint. The Redirect URLs card has an Add URL button and one URL, https://app.example.com/integrations/kudos/callback, with a yellow Domain not verified pill and a delete button. Below it (not in this picture) the Endpoints card lists the authorize, token and revoke URLs given in the steps above.
Auth: credentials and redirect URLs. The OAuth endpoints card sits below them.

About your domain
Your domain is claimed when you sign up and verified by KudosCRM during review. While it is only claimed, you can save and submit URLs on it. A URL on any other host is refused with “The host must be example.com or sit under it. Mark it test-only to use another host.” Nothing can be listed in the Marketplace until KudosCRM has verified the domain.

Scopes

Scopes are the access your app asks for, such as contacts:read (“Contacts and leads”) or tasks:write (“Tasks”). The admin reads them on the consent screen. The tab opens with “Ask for the least you need. Your reason is shown to admins on the consent screen.” The full list is under Scope catalog at the top right (/developers/scopes). The table has four columns: Scope, Request, Why your app needs it and Sensitivity.

  1. Choose Required, Optional or Off for each scope
    Required: the app can't work without it. Optional: the admin sees a switch on the consent screen and may turn it off. Off: not requested. The scopes you request are listed first; the ones you don't fold under a link with their count, for example More scopes (12). If your app uses the Telephony v1 contract (see Events), a line under the intro says “The telephony contract keeps contacts:read, users:read, activities:write and tasks:write on Required.”, and those four are locked on Required.
  2. Give a reason for each scope
    In Why your app needs it, say what your app does with it, in up to 140 characters, for example “Match each caller to a contact or lead so the call lands on the right record.” Every requested scope needs a reason before you can submit. Admins read it on the consent screen.
  3. For optional scopes, write the switch text
    Under the reason of an optional scope, click Consent switch · on by default (or · off by default) to open it. Choose whether it is On by default, and write what admins read when it is on (“When on: what your app does with it”) and when it is off (“When off: what happens instead”). For example, for leads:write: “Calls from unknown numbers create a new lead.” and “Calls from unknown numbers stay in the Unmatched calls list.” As the panel says, “Admins see this switch, and these sentences, on the consent screen.”

Each row also shows the scope's sensitivity, for example Personal data or Standard. Write access never includes read access, and no scope lets an app delete records.

The Scopes tab of the Acme Dialer editor. The intro reads Ask for the least you need. Your reason is shown to admins on the consent screen., followed by The telephony contract keeps contacts:read, users:read, activities:write and tasks:write on Required., with a Scope catalog link at the top right. A table with the columns Scope, Request, Why your app needs it and Sensitivity lists five scopes. contacts:read (Contacts and leads), users:read (Workspace users), activities:write (Activities) and tasks:write (Tasks) are each set to Required in a Required / Optional / Off control, with a filled reason, for example Match each caller to the right contact or lead so the call lands on that record. leads:write (Leads) is set to Optional, with the reason Create a lead when an unknown number calls., and its Consent switch · on by default panel is open: an On by default switch turned on, the sentences Calls from unknown numbers create a new lead. and Calls from unknown numbers stay in the Unmatched calls list., and the note Admins see this switch, and these sentences, on the consent screen. Sensitivity pills: Personal data for contacts:read and users:read, Standard for the other three. A More scopes (12) link sits at the bottom.
Scopes: Required, Optional or Off, each with a reason the admin reads.

Events

The Events tab has two cards: Events your app sends at the top, then Events your app receives.

Events your app sends is where you pick a contract (“Pick the category contract you implement. KudosCRM maps it — no custom code on either side.”). In Contract, choose None — REST only if your app only calls the REST API. Choose Telephony v1 for a calling or SMS app:

  • It requires the scopes contacts:read, users:read, activities:write and tasks:write, and may ask for leads:write as optional (so unknown callers can become leads). Picking the contract sets the four to Required for you and locks them there on the Scopes tab.
  • The card then lists every event in the contract, each labelled Required, If supported, Off by default or Flags only. The four required events, call.started, call.answered, call.missed and call.logged, are ticked for you and can't be unticked. Tick the others your product supports, such as contact.match, voicemail.received, sms.received, recording.ready and transcript.ready.
  • If a saved copy is missing a required event, the card says “Telephony v1 apps send … Tick them below before you submit.” Click Add them.
  • Read the telephony contract, under the list, opens the full contract at /developers/blueprints/telephony.

Events your app receives are the KudosCRM events sent to your server, such as contact.created or deal.stage_changed. Once you've entered a URL, the card says “Delivered to … signed with Standard Webhooks.” The full list of events, with every field and an example, is at /developers/events.

  1. Enter your webhook URL
    In Webhook URL, enter the URL that receives the events. Put {install_id} where each install's public id goes, for example https://api.example.com/kudos/webhooks/{install_id}. It must be a public address KudosCRM can reach: its host has to resolve on the public internet when you save, or the save is refused (see Troubleshooting).
  2. Say why you want the events
    Fill in Why your app wants these events, in up to 140 characters.
  3. Tick the events
    Events are grouped by object, for example Contacts · 2 of 4. Tick each event your app uses, and say in the box that opens under it what your app does with it. An event needs the matching read scope (for example contact.* needs contacts:read). If you tick one whose scope you don't request, the tab offers Request contacts:read right there.
The Events tab of the Acme Dialer editor, with Finish setup (7) at the top right and a small orange dot beside Events in the tab list, meaning there are edits not saved yet. The first card, Events your app sends, says Pick the category contract you implement. KudosCRM maps it — no custom code on either side. Its Contract menu is set to Telephony v1. Below it, the contract's events are listed with a label on the right: call.started, call.answered, call.missed and call.logged are Required, ticked and greyed so they can't be unticked; contact.match, voicemail.received, recording.ready and transcript.ready are If supported and ticked; sms.received, mms.received, summary.ready, sentiment.ready, call.tagged and call.noted are If supported and not ticked; contact.updated is Off by default and contact.deleted is Flags only, both unticked. A Read the telephony contract link ends the card. The second card, Events your app receives, says Delivered to https://api.example.com/kudos/webhooks/{install_id}, signed with Standard Webhooks. It has the Webhook URL field with that URL and the hint Put {install_id} where each install's public id goes., the Why your app wants these events field (Keep caller names in Acme Dialer in step with the contact in KudosCRM., 70 / 140), and the group Contacts · 2 of 4 with contact.created and contact.updated ticked, each with its own reason, and contact.deleted and contact.restored unticked, each needing contacts:read.
Events: the Telephony v1 contract for calling apps, then what KudosCRM sends you.

Listing

The Listing tab is what customers see in the Marketplace. A Marketplace card preview on the right updates as you type.

FieldWhat to putLimit
TaglineThe one line on the Marketplace card. Needed to submit.110 characters
DescriptionPlain text. A blank line starts a new paragraph. Needed to submit.4,000 characters
Price labelYour own plans: Free, Free and paid plans available, or Free to install · needs a {app name} plan. Listing on KudosCRM is free.One choice
LogoClick Upload logo. Square PNG, JPEG or WebP, at least 256 × 256. Needed to submit.2 MB
ScreenshotsClick Add. 16:10, at least 1600 × 1000, PNG, JPEG or WebP, each with an optional caption.Up to 6, 5 MB each, caption 60 characters
What it doesHighlights, each with a short title and one or two sentences. Click Add highlight.Up to 4
How it worksThree steps from install to the first result. Click Add step.Up to 3
What syncs, and which wayWhat lives in your app, which way it moves, and where it lands in KudosCRM, for example Calls → Call activities. Click Add a row.Up to 6 rows
Setup guideThe steps an admin follows, in order. Shown on the listing's Setup guide tab. Click Add a step.Up to 8 steps, 200 characters each

SVG and GIF images are refused. The logo and screenshots belong to this version: they are reviewed with it and go live when you release it.

The Listing tab of the Acme Dialer editor, every tab before Test now with a green check, and Checks not run yet beside a Submit v1.0 button at the top right. The left column shows Tagline (Every Acme Dialer call, logged on the right KudosCRM record., 60 / 110; The one line on the marketplace card), a four-paragraph Description (Plain text. A blank line starts a new paragraph), Price label set to Free (Describes Acme Dialer's own plans. Listing on KudosCRM is free), a Logo with a Replace logo button and the rule Square PNG, JPEG or WebP, at least 256 × 256. Reviewed with this version., and Screenshots · up to 6, 16:10, at least 1600 × 1000 with two screenshots, each with a delete button and a caption field, and an Add tile. On the right, a Marketplace card preview shows the logo, Acme Dialer, Acme Telecom, the tagline, Calling & SMS and an Install button. Below, four editable lists with counters: What it does (3 / 4 highlights, each a title and a sentence, with Add highlight), How it works (3 / 3 steps: Install, Match your team, Make a call), What syncs, and which way (3 / 6 rows such as Calls · Into KudosCRM · Contact timeline activities and Phonebook contacts · Out of KudosCRM · Contacts and leads, with Add a row) and Setup guide (4 / 8 steps, with Add a step). Each item has move up, move down and delete buttons.
Listing: the card, the logo and screenshots, and the sections of the listing page.

Test your app before you submit

A new app is private: it installs only in your company's developer workspace. To try it in other workspaces, add them as test workspaces.

  1. Add test workspaces (optional)
    Click Test workspaces in the left menu, then Add workspace. In Add a test workspace, pick one of the workspaces where you are an owner or admin. It must be another workspace, not your developer workspace. A test workspace is an ordinary workspace with its own data, plan and settings, so use one with test data. The page lists your test workspaces with the columns Workspace (with its plan under the name), Apps installed and Added, and an Open button and a delete button on each row. Under the list, a line counts them against the starter limit, and the card How test workspaces work sums up the rules.
  2. Choose where the app installs
    In the app editor, open the Test tab. Below Automated checks is the Where it installs card: “Until a release lists it, the app installs only where you say, through the real consent screen.” Choose Acme Telecom's workspace or Test workspaces too. This is saved at once. Manage test workspaces opens the Test workspaces page.
  3. Install your own working copy
    Start the install from your product, the way a customer will: your install page sends you to the KudosCRM consent screen (see “Connect a workspace with OAuth 2.0” below). On the consent screen, if you belong to several workspaces, pick your developer workspace or a test workspace under Workspace, then click Allow and install. Versions that aren't released yet, and redirect URLs marked test-only, work in these workspaces. Submitting a version for review doesn't stop your team installing it.
  4. Use the app for real
    Install, make some API calls, receive some events, then uninstall once. The checks read what really happened.
  5. Run the automated checks
    At the top of the Test tab, under Automated checks, click Run checks (later Run again). Each check reads Pass, Check, Fail, Not run or Running, with one line under it saying what KudosCRM saw, for example “1 install reached active in the last 30 days — the latest in Acme Telecom QA on 29 Oct.” or “v1.0 has no webhook URL, so there is nothing to sign.” Results are “Computed from your app's real installs and traffic in the last 30 days. Reviewers see the same results.” A summary line ends the card, for example “4 of 6 pass · last run 29 Oct 2026, 3:13 PM UTC”, and the Test tab shows how many checks are still to do.

The six checks:

  • Install completes through the real consent screen
  • Uninstall revokes tokens and the app gets 401 afterwards
  • Webhook signatures verified on a test delivery: KudosCRM sends a signed webhook.ping to your webhook URL, then the same ping with a wrong signature. Answer the first 2xx and the second 400 or 401.
  • Same event sent twice is applied once
  • Honors Retry-After on 429
  • Only requested scopes used in the last 7 days
The Test workspaces page of the developer console, subtitled Your own workspaces where versions install before they are listed., with an Add workspace button at the top right. A table with the columns Workspace, Apps installed and Added lists one test workspace: Acme Telecom QA, Free plan, 0 apps installed, added 29 Oct 2026, with an Open button and a delete button. Under it the line reads 1 of 5 test workspaces while KudosCRM hasn't approved your first app yet. The limit lifts with that approval. Removed workspaces still count until your first app is approved. A card titled How test workspaces work has three points: apps with test distribution install in Acme Telecom's own workspace and in the workspaces listed here, listed apps install anywhere, and you choose where an app installs on its Test tab; you need to be an admin of a workspace to add it, and the install runs through the real consent screen; a test workspace is an ordinary workspace that keeps its own data, plan and settings, so use one with test data.
Test workspaces: your own workspaces where unlisted versions install.
The Test tab of the Acme Dialer editor, with 4 of 6 checks pass beside the Submit v1.0 button at the top right and Test showing 2 to do in the tab list. The first card, Automated checks, is subtitled Computed from your app's real installs and traffic in the last 30 days. Reviewers see the same results., with a Run again button. It lists six checks, each with a status pill and one explaining line: Pass, Install completes through the real consent screen; Pass, Uninstall revokes tokens and the app gets 401 afterwards; Not run, Webhook signatures verified on a test delivery (v1.0 has no webhook URL, so there is nothing to sign); Pass, Same event sent twice is applied once; Not run, Honors Retry-After on 429 (no request was rate limited in the last 30 days); Pass, Only requested scopes used in the last 7 days. The card ends 4 of 6 pass · last run 29 Oct 2026, 3:13 PM UTC. The second card, Where it installs, says Until a release lists it, the app installs only where you say, through the real consent screen., with two choices, Acme Telecom's workspace and Test workspaces too (selected), the line Acme Telecom's workspace and your test workspaces can install it., and a Manage test workspaces link.
Test: run the automated checks, and choose where the app installs before it is listed.

Starter limits

  • A new developer company can have up to 5 apps and 5 test workspaces until KudosCRM approves its first app.
  • The limits lift by themselves when KudosCRM approves your first app. KudosCRM can also raise or lift them for your company if you write in.
  • Until then, every test workspace you ever added counts, including ones you removed or no longer administer. Adding one back takes no new room.
  • After that, the platform limits apply: 50 apps per company and 25 test workspaces.

Submit your app for review

  1. Open the Submit tab
    Click Submit v1.0 at the top right, or the Submit tab. The tab is headed Submit v1.0 for review. Under Ready to send, each tab reads Done with a green check, or what it still needs, with a button to go there. Automated checks shows how many pass, for example “4 of 6 pass”, with a See checks button; it gets its check only when every check passes. Checks that don't pass don't stop you submitting, but reviewers see them.
  2. Clear anything under “Before you send”
    This box lists what blocks the submission, for example “Save your edits first — review sees the saved copy.” (click Save edits) or “Acme Telecom hasn't accepted the partner agreement yet.” (click Read and accept it).
  3. Read the domain note, if there is one
    If your domain isn't verified yet, a blue box above the form says “KudosCRM verifies your domain, example.com, during review. Until it's verified, your app can't be listed in the marketplace.” You can still submit.
  4. Say what changed
    In What changed, say what is new in this version and why (“Reviewers read this first. Say what's new and why.”).
  5. Link an install video
    In Install video URL, paste a Loom or YouTube link that shows the install, start to finish, and an uninstall.
  6. Give reviewers a test login
    Under Reviewer test account, enter a Reviewer username or email and Reviewer password for a test account in your app. Only KudosCRM reviewers can see them, after a security check, and they're deleted once review ends. Each new round needs them again.
  7. Confirm and submit
    Tick “I confirm the app follows the partner agreement and asks only for the data it uses.” (partner agreement is a link to it). Click Submit for review. A message confirms “v1.0 sent to review”.
The Submit tab of the Acme Dialer editor, headed Submit v1.0 for review, with 4 of 6 checks pass beside the Submit v1.0 button at the top right. A Ready to send list shows Basic info, Auth, Scopes, Events and Listing each as Done with a green check, and Automated checks · 4 of 6 pass with an empty circle and a See checks button. A blue info box reads KudosCRM verifies your domain, example.com, during review. Until it's verified, your app can't be listed in the marketplace. Below: a What changed box with a one-paragraph summary of the first version (hint: Reviewers read this first. Say what's new and why.), an Install video URL field with a Loom link (hint: A Loom or YouTube link showing the install, start to finish.), and a Reviewer test account section explaining that only KudosCRM reviewers can see these, after a security check, and they're deleted once review ends, with Reviewer username or email (reviewer@example.com) and a masked Reviewer password with a show button. Last come an unticked checkbox reading I confirm the app follows the partner agreement and asks only for the data it uses., and the buttons Submit for review and Back to checks.
Submit: what changed, an install video, a reviewer login and your confirmation.

While a version is in review, it can't be edited. The editor says “v1.0 is submitted and waiting for a reviewer, so it can't be edited until our reviewers decide. Review usually takes up to 5 business days.”

What KudosCRM checks in review

A KudosCRM reviewer reads your submission, the automated check results, a preview of your listing and consent screen, and a list of what changed since your last released version. They tick a checklist of seven items:

  • Each scope is needed for what the listing says.
  • Consent wording is plain and accurate.
  • Privacy policy and terms load.
  • Install video shows install and uninstall.
  • Reviewer login works in the test workspace.
  • Listing claims are true.
  • Support contact answers.

During your first review, KudosCRM also verifies your domain. The reviewer then decides:

  • Approve: the editor says “KudosCRM approved v1.0. Release it when you're ready…” and the button at the top becomes Release v1.0.
  • Request changes: the editor says “KudosCRM asked for changes to v1.0: “…” Edit it and submit again.” The badge by the app's name reads v1.0 · changes requested, and the Submit tab shows a Changes requested box with the decision date and the reviewer's note. Fix what the note asks, save, and submit again. The reviewer fields are empty again, with the line “Enter the test login again: the one you gave last round was deleted when that review ended.” This starts a new round.
  • Reject: the editor says “KudosCRM didn't approve this version: “…”” Editing starts a new copy.
The app editor for Acme Dialer after a reviewer asked for changes. The badge by the name reads v1.0 · changes requested. A yellow banner across the top reads KudosCRM asked for changes to v1.0: “Add a privacy policy that names Acme Telecom.” Edit it and submit again. The Submit tab, headed Submit v1.0 for review, starts with a box showing a Changes requested pill, Decided 29 Oct 2026, and the same quoted note. The Ready to send list, the domain note, What changed and Install video URL follow, still filled in. Under Reviewer test account, a bold line reads Enter the test login again: the one you gave last round was deleted when that review ended., and the Reviewer username or email and Reviewer password fields are empty.
When KudosCRM asks for changes, fix them and submit again.

Release your approved app

  1. Click Release v1.0
    A dialog asks “Release v1.0?” and says new installs get v1.0 at once.
  2. Choose where it goes
    Under Where it goes, pick one: List it in the marketplace (“Every KudosCRM workspace can find and install it.”), Test workspaces only (your company's workspace and your test workspaces; it isn't listed), or Acme Telecom's workspace only (only your own workspace; it isn't listed).
  3. Click Release v1.0
    Once listed, the editor says “v1.0 is live in the marketplace.” and offers View listing. On My apps the row reads Listed · v1.0 · Public marketplace.
The Release v1.0? dialog over the blurred app editor, where a v1.0 approved badge, a green approval banner and a Release v1.0 button can be made out. The dialog says New installs get v1.0 at once. Admins of existing installs are asked to approve any scope it adds; nothing is revoked while they decide. Under Where it goes are three options: List it in the marketplace (selected; Every KudosCRM workspace can find and install it.), Test workspaces only (Acme Telecom's workspace and your test workspaces can install it. It isn't listed.) and Acme Telecom's workspace only (Only your own workspace can install it. It isn't listed.). Buttons: Cancel and Release v1.0, and a close button at the top right.
Release: list it in the Marketplace, or keep it to your own workspaces.

Every release needs your domain verified when the app has URLs on it, whether it goes to the Marketplace or to your test workspaces. KudosCRM verifies the domain during review. If it isn't verified yet, the release is refused with “Acme Dialer can't be released until KudosCRM verifies Acme Telecom's domain, example.com…”. Ask KudosCRM to verify it, then release again.

Once an app is public, only KudosCRM can take it off the Marketplace.

Where your app appears

  • In every KudosCRM workspace: Settings › Platform › Marketplace shows your card in its category. Its listing page (for example Marketplace › Calling & SMS › Acme Dialer) shows your logo, name, “by Acme Telecom” and tagline, an Install button that sends admins to your install URL, a Visit example.com link to your company's website (from the Website field, without www.), and your price label, for example “Free to install”. Its tabs are Overview, Permissions, Events, Setup guide and Support. For a Telephony v1 app, the Overview starts with a What you will see on a contact card: a sample call marked “Example”, showing only what your app says it sends (for example “Transcript attached”). Then come About Acme Dialer (your description), What it does, What syncs, and which way, How it works and Screenshots. On the right, Data access sums up what the app can see, can do and never does, with See every permission; Details shows the category, what it works with, plans and version; and Publisher links your website, privacy policy and terms of service and says your company is responsible for the app and its support.
  • On kudoscrm.com: your tile on kudoscrm.com/integrations and your own page there, built from the same app registry. They appear after the next website build, not the moment you release.
  • After install: the customer manages your app under Settings › Connected apps, where they can pause, reconnect or uninstall it.
The Acme Dialer listing page inside a customer's KudosCRM workspace. The Settings menu on the left has Platform open with Marketplace selected, and the breadcrumb reads Marketplace › Calling & SMS › Acme Dialer. The header shows the logo, Acme Dialer, by Acme Telecom and the tagline Every Acme Dialer call, logged on the right KudosCRM record. On the right are an Install button, a Visit example.com button and the line Free to install. Tabs: Overview (selected), Permissions, Events, Setup guide, Support. The Overview starts with a What you will see on a contact card marked Example: a sample call row, Inbound call · answered by Priya Raman, via Acme Dialer, with a playback bar and a Transcript attached tag. Then come About Acme Dialer with the four-paragraph description, What it does with three highlights, What syncs, and which way as a table (Calls → Contact timeline activities, Missed calls → Follow-up tasks, Phonebook contacts ← Contacts and leads), How it works in three steps, and Screenshots with two captioned images. The right column has a Data access card (Can see: contacts, leads, companies, users; Can do: activities, tasks, and leads if you allow it; Never: deals, quotes, invoices, email content, deletes; a See every permission button), a Details card (Category Calling & SMS; Works with Contacts, Leads, Activities, Tasks; Plans All KudosCRM plans; Version 1.0 · listed Oct 2026) and a Publisher card (Acme Telecom with Website, Privacy policy and Terms of service links, and a note that KudosCRM reviews every app's access and listing before it goes live and Acme Telecom is responsible for the app and its support).
A listed app in Settings › Marketplace in every KudosCRM workspace.

Release a new version

  1. Edit the app
    Open the app from My apps and change any tab. A banner says you are editing a pending copy: the live version keeps running for its installs until the new version is approved. Scopes, redirect URLs and events are reviewed fields.
  2. Submit it
    Every version goes through review, the first and every one after it. A new logo and new screenshots are reviewed with the version and show in the Marketplace only after you release it.
  3. Release it
    New installs get the new version at once. If it asks for a scope an existing install never approved, that workspace's admin sees “Acme Dialer 1.1 asks for more access” on Connected apps. Nothing is revoked while they decide. If you dropped a scope, it leaves every install's grant.

Connect a workspace with OAuth 2.0 and PKCE

This is standard OAuth 2.0 authorization code with PKCE (RFC 7636). Only S256 is accepted. Any off-the-shelf OAuth library works. The discovery document lists every URL:

curl https://api.kudoscrm.com/.well-known/oauth-authorization-server
  1. Make a verifier and its challenge
    The verifier is 43–128 characters of [A-Za-z0-9-._~]. Keep it, with a random state, on your server until the admin comes back.
    CODE_VERIFIER=$(openssl rand -base64 48 | tr -d '=+/' | cut -c1-64)
    CODE_CHALLENGE=$(printf '%s' "$CODE_VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr '+/' '-_' | tr -d '=')
  2. Send the admin to the consent screen
    Your install URL redirects the admin's browser to:
    https://app.kudoscrm.com/oauth/authorize?response_type=code
      &client_id=app_acme_dialer
      &redirect_uri=https%3A%2F%2Fapp.example.com%2Fintegrations%2Fkudos%2Fcallback
      &scope=contacts%3Aread%20users%3Aread%20activities%3Awrite%20tasks%3Awrite%20leads%3Awrite
      &state=5f2c9d1e
      &code_challenge=$CODE_CHALLENGE
      &code_challenge_method=S256
    redirect_uri must match one of your redirect URLs character for character. Leave scope out to ask for everything the version requests. You can never ask for more.
  3. The admin approves
    The consent screen says “Acme Dialer wants to connect to your KudosCRM workspace”, with “Published by Acme Telecom · example.com” under it. It shows who is signed in, with a Not you? link. Under Workspace, an admin who belongs to several workspaces picks one from a menu; an admin with only one workspace sees its name and their role instead, for example “Northwind Traders · You are the owner”. They see what your app “will be able to see” and “will be able to do” (one row per scope, with your reason), optional scopes marked Optional with a checkbox, and a Never: line (for example “delete records, or see deals, quotes, invoices or email content”). They click Allow and install or Cancel. The footer names the host they'll return to and says they can remove access any time in Settings › Connected apps, and that your privacy policy and terms apply to the data your app receives. For an app KudosCRM has reviewed, a line under the card adds “KudosCRM checked this app's identity and the access it asks for.” with a How app review works link.
  4. Check what comes back
    On allow, the browser returns to your redirect URL with code (a kac_… code, valid 10 minutes, single use), your state and iss. Check that state is yours and iss is https://api.kudoscrm.com. On cancel you get error=access_denied.
  5. Exchange the code for tokens
    Send the client secret in HTTP Basic or in the form body, never both and never in the query string.
    curl https://api.kudoscrm.com/oauth/token \
      -u "app_acme_dialer:$CLIENT_SECRET" \
      -d grant_type=authorization_code \
      -d code="$CODE" \
      -d redirect_uri=https://app.example.com/integrations/kudos/callback \
      -d code_verifier="$CODE_VERIFIER"
    The answer has access_token (kat_…, 1 hour), refresh_token (krt_…), scope, install_id (inst_…), workspace (id, name), ingest_url and setup_url. Store the tokens per install.
  6. Send the admin to setup_url
    It opens KudosCRM on the right workspace to finish setup. For a telephony app, that is where the admin matches your agents to their users and chooses what happens to unknown callers and missed calls. Until they finish, Connected apps shows Finish setting up.
  7. Call the API
    curl "https://api.kudoscrm.com/api/v1/contacts?filter[phone]=%2B15555550142" \
      -H "Authorization: Bearer $ACCESS_TOKEN"
    A token acts as the install's acting admin, inside the scopes granted. A missing scope answers 403 with code: insufficient_scope and meta.required_scope.
  8. Refresh before the hour is up
    curl https://api.kudoscrm.com/oauth/token -u "app_acme_dialer:$CLIENT_SECRET" \
      -d grant_type=refresh_token -d refresh_token="$REFRESH_TOKEN"
    Refresh tokens rotate: every refresh returns a new one, and the one you sent stops working. Store the new one before you use the new access token. Refresh tokens last 90 days, renewed on each rotation.
  9. Revoke when a customer disconnects in your product
    curl https://api.kudoscrm.com/oauth/revoke -u "app_acme_dialer:$CLIENT_SECRET" -d token="$REFRESH_TOKEN"
    The install then needs reconnecting, and your webhook hears integration.disconnected with reason: revoked.
The KudosCRM consent screen, with the Acme Dialer logo and the KudosCRM logo side by side at the top. The title reads Acme Dialer wants to connect to your KudosCRM workspace, with Published by Acme Telecom · example.com under it. Next: Signed in as Maya Patel (maya.patel@example.net) with a Not you? link, and Workspace: Northwind Traders · You are the owner, shown as plain text because she has only one workspace. The section Acme Dialer will be able to see lists Contacts, leads and companies in Northwind Traders (names, emails and phone numbers, with the app's reason) and Workspace users (names and emails of your team, with the reason). The section Acme Dialer will be able to do lists Log activities and Create and update tasks, each with its reason, and Create and update leads with an Optional pill, the sentence Calls from unknown numbers create a new lead., and a ticked checkbox. A Never line reads Never: delete records, or see deals, quotes, invoices or email content. Buttons: Cancel and Allow and install. The footer reads You'll return to app.example.com. Remove access any time in Settings › Connected apps. Acme Dialer's privacy policy and terms apply to data it receives. Under the card: KudosCRM checked this app's identity and the access it asks for., with a How app review works link.
The consent screen the customer's admin reads before your app is installed.

Never refresh the same token twice
Two refreshes of one token within 30 seconds are treated as a race: the second gets invalid_grant (refresh_token_already_rotated) and nothing is revoked. Use the tokens the first refresh returned. A rotated token presented later is treated as stolen: the install's grant is revoked and the admin must reconnect. The same goes for an authorization code used twice.

Receive signed webhooks

When an admin installs your app, KudosCRM creates one webhook subscription for that install from your Events tab. You never create it, and the admin can't edit it. Each event arrives as a JSON envelope:

{
  "event_id": "evt_4d88894b1eae8347dea3c548",
  "type": "deal.stage_changed",
  "occurred_at": "2026-10-08T10:42:18Z",
  "tenant_id": "3f6a1c2e-8b4d-4e7f-9a10-5c2d8e7f6a31",
  "install_id": "inst_7Hq2XcRm4P",
  "payload_version": 2,
  "origin": { "kind": "user", "id": "5e2b9d14-…" },
  "data": { "deal": { … }, "from_stage": { … }, "to_stage": { … } }
}

Each delivery carries these headers. Verify one of the two signature schemes:

Content-Type: application/json
User-Agent: KudosCRM-Webhooks/1.0
X-Kudos-Signature: t=1791456139,v1=7697…0d2d
X-Kudos-Event: deal.stage_changed
X-Kudos-Delivery: evt_4d88894b1eae8347dea3c548
X-Kudos-Delivery-Attempt: 1
webhook-id: evt_4d88894b1eae8347dea3c548
webhook-timestamp: 1791456139
webhook-signature: v1,sYxoDmpF…L0dI=

The signing key. Each install has its own key, derived from your app's signing secret and the install's id: "whsec_" + base64(HMAC-SHA256(key = signing secret exactly as issued, data = "kudos-install-v1:" + install_id)). You store one secret per app, and a key for one install never verifies another install's deliveries.

Verify in Node (the Standard Webhooks headers). Verify the raw body, before any JSON parsing, and reject timestamps more than 5 minutes from your clock:

import crypto from "node:crypto";

export function installSigningKey(appSigningSecret, installId) {
  const digest = crypto.createHmac("sha256", appSigningSecret)
    .update(`kudos-install-v1:${installId}`).digest("base64");
  return `whsec_${digest}`;
}

export function verifyDelivery({ rawBody, headers, appSigningSecret, installId,
                                 now = Math.floor(Date.now() / 1000), toleranceS = 300 }) {
  const id = headers["webhook-id"];
  const timestamp = Number(headers["webhook-timestamp"]);
  if (!id || !Number.isFinite(timestamp) || Math.abs(now - timestamp) > toleranceS) return false;
  const key = Buffer.from(installSigningKey(appSigningSecret, installId).slice("whsec_".length), "base64");
  const expected = crypto.createHmac("sha256", key).update(`${id}.${timestamp}.`).update(rawBody).digest();
  return String(headers["webhook-signature"] || "").split(" ").some((entry) => {
    const [version, signature] = entry.split(",", 2);
    const given = Buffer.from(signature || "", "base64");
    return version === "v1" && given.length === expected.length && crypto.timingSafeEqual(given, expected);
  });
}

Verify in Python:

import base64, binascii, hashlib, hmac, time

def install_signing_key(app_signing_secret: str, install_id: str) -> str:
    digest = hmac.new(app_signing_secret.encode(), f"kudos-install-v1:{install_id}".encode(), hashlib.sha256).digest()
    return "whsec_" + base64.b64encode(digest).decode()

def verify_delivery(raw_body: bytes, headers: dict, app_signing_secret: str, install_id: str, tolerance_s: int = 300) -> bool:
    msg_id, timestamp = headers.get("webhook-id"), headers.get("webhook-timestamp", "")
    if not msg_id or not timestamp.isdigit() or abs(int(time.time()) - int(timestamp)) > tolerance_s:
        return False
    key = base64.b64decode(install_signing_key(app_signing_secret, install_id).removeprefix("whsec_"))
    expected = hmac.new(key, f"{msg_id}.{timestamp}.".encode() + raw_body, hashlib.sha256).digest()
    for entry in headers.get("webhook-signature", "").split(" "):
        version, _, signature = entry.partition(",")
        try:
            given = base64.b64decode(signature, validate=True)
        except (binascii.Error, ValueError):
            continue
        if version == "v1" and hmac.compare_digest(given, expected):
            return True
    return False

Prefer X-Kudos-Signature? It is t=<unix>,v1=<hex>: the hex HMAC-SHA256 of "<t>.<raw body>", keyed by the derived key string exactly as computed, whsec_ included. After you rotate the signing secret with a grace period, deliveries carry two signatures. Accept the delivery if any one matches.

Answering, retries and duplicates

Your answerWhat KudosCRM does
2xx within 8 secondsDelivered. Do slow work after you answer.
408, 429, 5xx, a timeout or a network errorRetries: 6 attempts in all, after about 30 s, 2 min, 10 min, 30 min and 1 h (±25 %). A Retry-After you send is honoured, up to 2 hours.
Any other 4xx, or a redirectDead-lettered at once, no retry. Redirects are never followed.
410 GoneDead-lettered, and this install's subscription stops.
  • Deduplicate on event_id. It is the same on every retry and every replay. An admin can resend any event from Manage › Activity log, and it arrives with the same event_id.
  • Ten dead letters in a row stop the subscription. The admin sees “Deliveries stopped after repeated failures” on Connected apps, and Retry resends them, oldest first.
  • Your own writes never come back. An event your app caused is not sent to it.
  • Lifecycle events. integration.installed arrives after your first code exchange. integration.disconnected arrives with a reason: uninstalled, revoked or reauth_required.
  • Answer webhook.ping. Verify its signature, then answer 2xx, even though it isn't an event you subscribed to.

Sending events to KudosCRM (telephony apps): POST each event to the install's own ingest_url from the token response, with install_id in the body, signed with X-Kudos-Signature using the install's derived key. Each event is applied once, so you can resend safely. The full contract is at /developers/blueprints/telephony.

Limits and URLs

WhatValue
Developer consolehttps://app.kudoscrm.com/developers
Developer docshttps://app.kudoscrm.com/docs/build-an-app/
Scope catalog · event catalog · telephony contract/developers/scopes · /developers/events · /developers/blueprints/telephony
AuthorizeGET https://app.kudoscrm.com/oauth/authorize
Token · revokePOST https://api.kudoscrm.com/oauth/token · POST https://api.kudoscrm.com/oauth/revoke
Discoveryhttps://api.kudoscrm.com/.well-known/oauth-authorization-server
REST API basehttps://api.kudoscrm.com/api/v1/
Client id · secretsapp_<key> · client secret kcs_… · signing secret whsec_…
Token lifetimesCode 10 minutes, single use · access token 1 hour · refresh token 90 days, rotates on every use
API rate limit2,400 requests an hour per install by default. Responses carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset.
WebhookAnswer within 8 seconds · signature valid for 5 minutes · 6 attempts
Redirect URLsUp to 10, https:// on your domain (test-only ones may be http://localhost)
Starter limits5 apps, 5 test workspaces until your first app is approved
Platform limits50 apps per company, 25 test workspaces
Logo · screenshotsSquare, ≥ 256 × 256, ≤ 2 MB · 16:10, ≥ 1600 × 1000, ≤ 5 MB, up to 6
Request logEvery request your tokens make, kept 30 days, under Logs

Troubleshooting

What you seeWhat it meansWhat to do
“Use 2–60 lowercase letters, digits or underscores, starting with a letter.”The key's format is wrong.Fix the key, for example acme_dialer.
“acme_dialer is already taken. Choose another.”Another app uses that key.Choose another key.
“zoom is reserved for a well-known brand. Choose a key with your company's name in it.”Brand names and keys starting kudos are reserved.Put your company's name in the key.
“New publishers can have up to 5 apps until KudosCRM approves their first one.”You reached the starter app limit.Get your first app approved, or ask KudosCRM to raise the limit.
“New publishers can have up to 5 test workspaces until KudosCRM approves their first app. Removed workspaces still count until your first app is approved.”You reached the starter test workspace limit.Reuse a workspace you already added, get your first app approved, or ask KudosCRM.
“Acme Telecom has 50 apps — the most a publisher can have. Contact KudosCRM if you need more.”The platform app limit.Contact KudosCRM.
“The host must be example.com or sit under it. Mark it test-only to use another host.”A redirect, install, app or help URL is on another domain.Use a host on your domain, or tick Test workspaces only for a redirect URL.
“KudosCRM can only send to a public address, and api.example.com isn't one it can reach. Check the host name.”The webhook URL's host doesn't resolve on the public internet, or points to a private address such as localhost.Use a public host that has a DNS record and is reachable from the internet, then save again.
“The logo must be square, at least 256 × 256. This one is …”Wrong logo size.Upload a square PNG, JPEG or WebP of 256 × 256 or more.
“Screenshots are 1600 × 1000, or larger at 16:10. This one is …”Wrong screenshot size.Export at exactly 16:10, at least 1600 × 1000.
“A listing has at most 6 screenshots. Delete one first.”You already have six.Delete one, then add.
“Upload a square logo on the Listing tab. Every app in the KudosCRM Marketplace shows one.”Submit needs a logo.Upload it on the Listing tab.
“Acme Telecom hasn't accepted the partner agreement yet. Accept it first.”Submit needs the agreement.Open Partner agreement and accept it.
“KudosCRM published version … of the partner agreement…”A new version is in force.Accept the new version, then submit.
“Nothing has changed since v1.0.”The working copy equals the live version.Make a change before you submit.
“Give reviewers a login for a test account in your app.” / “Add a link to a video of the install, start to finish.”A submission field is empty.Fill in the reviewer login or the install video URL.
“Acme Dialer can't be released until KudosCRM verifies Acme Telecom's domain, example.com…”The domain isn't verified yet.Ask KudosCRM to verify it, then release again.
403 insufficient_scopeThe install's grant doesn't include the scope this call needs. meta.required_scope names it.Request the scope in a new version, or stop making that call.
429 with Retry-AfterThe install used its hourly quota.Wait the number of seconds in Retry-After. The review checks this.
503 app_pausedThe customer paused your app.Wait. Events you send are kept and applied when they resume.
403 app_suspendedKudosCRM suspended your app.Contact KudosCRM.
401, then invalid_grant on refreshThe install needs reconnecting (its grant was revoked).Send the admin through /oauth/authorize again.
The Webhook signatures verified on a test delivery check failsYour endpoint answered the wrong-signature ping with 2xx, or the real ping with an error.Verify the signature first; answer 400 or 401 when it fails and 2xx when it passes.
A check reads Not runThere was nothing to measure in the last 30 days. The line under the check says why, for example “v1.0 has no webhook URL, so there is nothing to sign.”Fill in what's missing (here, the webhook URL on the Events tab), install the app in a test workspace, use it for real, then Run again.

Frequently asked questions

Does it cost anything to build or list an app?

No. Becoming a developer is free on any plan, the free plan included, and listing on KudosCRM is free. The Price label describes your own product's plans, not a KudosCRM fee.

How long does review take?

The console says “Review usually takes up to 5 business days.”

Who owns the customer data my app reads?

The workspace's data stays the customer's, in their KudosCRM workspace. Your app sees only what the admin approved on the consent screen. The consent screen tells the admin that your privacy policy and terms apply to the data your app receives, and your listing says your company is responsible for the app and its support. The admin can remove access at any time in Settings › Connected apps, which revokes your tokens.

Can I build a private app just for my own workspace?

Yes. Every app starts private: it installs only in your company's developer workspace. You can test it there, and in your test workspaces, without review. To release a version to your own workspace, choose Acme Telecom's workspace only in the release dialog; releasing needs an approved version. If only your workspace will ever use it, an API token and an outbound webhook are simpler than an app.

Can I change the app's key later?

No. The key is permanent. Everything else, including the name, can change in a later version.

Can more than one person on my team work on the app?

Yes. Every admin of your developer workspace with the Build, submit & release developer apps permission is a developer. See them under Team.

Does a test workspace need a paid plan?

No. A test workspace is any workspace where you are an owner or admin, other than your developer workspace.

Can I take my app off the Marketplace?

Once an app is public, only KudosCRM can take it off. Contact KudosCRM. Existing installs keep working when an app is taken off.

Why does my app not show on kudoscrm.com yet?

The website is rebuilt from the app registry. Your app appears there after the next website build. It shows in Settings › Marketplace in every workspace as soon as you release it.

Learn more

Have an account issue this guide doesn't cover?

Open a ticket Track your requests

Start free today

Ready to give your team a CRM they'll actually use?

Start free. Bring your whole team. Cancel whenever (you won't).