10x CRM Inbound App Setup

A walkthrough of how we implemented Descope's Inbound Apps feature in 10x CRM

Why use Inbound Apps?

With Inbound Apps, AI agents and third-party applications can securely access 10x CRM data with proper authentication and authorization.

1

Creating the 10x CRM Inbound App

We started by creating a new inbound app in the Descope Console.

Descope Console showing the creation of a 10x CRM Inbound App with name and description fields
2

Defining CRM-Specific OAuth Scopes

For our 10x CRM, we defined granular scopes to control access to different parts of the application. We createdcontacts:read anddeals:read scopes, with clear descriptions of what they allow.

Descope Console showing OAuth scopes configuration for CRM permissions
3

Designing the 10x CRM Consent Flow

We designed a user-friendly consent flow that clearly explains to users what permissions they're granting to third-party applications. The flow first checks if the user is logged in, then presents a consent screen that describes the scopes the application is requesting access to.

Descope Console showing OAuth consent flow configuration with authentication and authorization steps
How We Protected the 10x CRM API Endpoints

After setting up our Inbound App in the Descope Console, we implemented the necessary code in our 10x CRM application to validate tokens and enforce scope-based permissions:

OAuth Middleware for CRM API Protection

We implemented a custom OAuth middleware that validates JWT tokens issued by Descope, extracts the scopes, and ensures that API requests have the necessary permissions.

// OAuth middleware for 10x CRM API protection
import { NextRequest, NextResponse } from "next/server"
import descopeSdk from '@descope/node-sdk'

export function withOAuth(handler, requiredScopes = []) {
  return async function (req: NextRequest) {
    const token = req.headers.get('authorization')?.replace('Bearer ', '')
    if (!token) {
      return NextResponse.json({ error: 'Missing token' }, { status: 401 })
    }

    try {
      const validationResponse = await sdk.validateSession(token)
      const scopes = (validationResponse.token.scope as string).split(' ')

      if (requiredScopes.some(scope => !scopes.includes(scope))) {
        return NextResponse.json({
          error: 'Insufficient permissions',
          requiredScopes
        }, { status: 403 })
      }

      return handler(req, { scopes })
    } catch (error) {
      return NextResponse.json({ error: 'Invalid token' }, { status: 401 })
    }
  }
}

Protected CRM API Routes

We applied the OAuth middleware to our CRM API routes, ensuring that each endpoint requires the appropriate scopes. For example, the contacts API requires the "contacts:read" scope for GET requests.

// Example protected CRM API route
export const GET = withOAuth(
  async (req, context) => {
    // Your API logic here
    return NextResponse.json({ data: "Your response" })
  },
  ["contacts:read"]
)

Ready to Secure Your APIs?

Follow our implementation guide to create your own secure, OAuth-enabled CRM application with Descope.