Example Flows
This guide illustrates common integration patterns with sequence diagrams and code examples.
Important: Consent must always be collected before processing user data. This ensures compliance with privacy regulations and establishes a clear consent record.
User Sign Up
When a new user registers on your platform, collect consent first on a temporary ID, then create the user and link the consent.
Sequence Diagram
sequenceDiagram
participant U as User
participant F as Frontend
participant B as Your Backend
participant R as Redacto API
Note over U,R: Phase 1: Collect Consent First
U->>F: Fill registration form
F->>F: Generate temporary ID (UUID)
F->>B: Request token for temp ID
B->>R: POST /tokens/generate (org_user_id: temp_xxx)
R-->>B: JWT tokens
B-->>F: Return tokens
F->>F: Show RedactoNoticeConsent modal
U->>F: Accept consent
F->>R: Submit consent (via SDK)
R-->>F: Consent recorded (user created)
Note over U,R: Phase 2: Create User & Link
F->>B: Submit registration with temp ID
B->>B: Create user in your system
B->>R: POST /consent-users/ (org_user_id: user_123)
R-->>B: Primary user created
B->>R: POST /consent-users/link-users
Note right of B: primary: user_123<br/>alias: temp_xxx
R-->>B: Users linked
B-->>F: Registration complete
F-->>U: Redirect to dashboard
Backend Code
import express, { Request, Response } from "express";
import axios from "axios";
const app = express();
app.use(express.json());
const CMS_API_KEY = process.env.CMS_API_KEY;
const REDACTO_BASE_URL = process.env.REDACTO_BASE_URL || "https://api.redacto.io";
const ORG_UUID = process.env.ORG_UUID;
const WORKSPACE_UUID = process.env.WORKSPACE_UUID;
// Step 1: Generate token for temporary ID (before consent)
app.post("/api/consent/temp-token", async (req: Request, res: Response) => {
const { temp_id } = req.body;
if (!temp_id) {
res.status(400).json({ error: "temp_id is required" });
return;
}
try {
const response = await axios.post(
`${REDACTO_BASE_URL}/consent/public/organisations/${ORG_UUID}/workspaces/${WORKSPACE_UUID}/tokens/generate`,
{ org_user_id: temp_id },
{
headers: {
"X-CMS-API-Key": CMS_API_KEY,
"Content-Type": "application/json",
},
}
);
res.json({
token: response.data.detail.token,
refresh_token: response.data.detail.refresh_token,
});
} catch (error) {
console.error("Error generating token:", error);
res.status(500).json({ error: "Failed to generate token" });
}
});
// Step 2: Complete registration after consent is given
app.post("/api/register", async (req: Request, res: Response) => {
const { email, password, name, temp_id } = req.body;
try {
// 1. Create user in your system
const user = await createUser({ email, password, name });
// 2. Create primary consent user in Redacto
await axios.post(
`${REDACTO_BASE_URL}/consent/organisations/${ORG_UUID}/workspaces/${WORKSPACE_UUID}/consent-ledger/consent-users/`,
{
org_user_id: user.id,
primary_email: email,
name: name,
},
{
headers: {
"X-CMS-API-Key": CMS_API_KEY,
"Content-Type": "application/json",
},
}
);
// 3. Link temp consent user to the primary user
if (temp_id) {
await axios.post(
`${REDACTO_BASE_URL}/consent/organisations/${ORG_UUID}/workspaces/${WORKSPACE_UUID}/consent-ledger/consent-users/link-users`,
{
primary_org_user_id: user.id,
alias_org_user_ids: [temp_id],
},
{
headers: {
"X-CMS-API-Key": CMS_API_KEY,
"Content-Type": "application/json",
},
}
);
}
// 4. Generate new tokens for the registered user
const tokenResponse = await axios.post(
`${REDACTO_BASE_URL}/consent/public/organisations/${ORG_UUID}/workspaces/${WORKSPACE_UUID}/tokens/generate`,
{ org_user_id: user.id, email: email },
{
headers: {
"X-CMS-API-Key": CMS_API_KEY,
"Content-Type": "application/json",
},
}
);
res.json({
user: { id: user.id, email, name },
token: tokenResponse.data.detail.token,
refresh_token: tokenResponse.data.detail.refresh_token,
});
} catch (error) {
console.error("Registration error:", error);
res.status(500).json({ error: "Registration failed" });
}
});
// Helper function (implement based on your auth system)
async function createUser(data: { email: string; password: string; name: string }) {
// Your user creation logic here
return { id: `user_${Date.now()}`, ...data };
}
app.listen(3000, () => console.log("Server running on port 3000"));Frontend Code
import { RedactoNoticeConsent } from "@redacto.io/consent-sdk-react";
import { useState, useEffect } from "react";
import { v4 as uuidv4 } from "uuid";
const NOTICE_UUID = process.env.NEXT_PUBLIC_NOTICE_UUID;
const REDACTO_BASE_URL = process.env.NEXT_PUBLIC_REDACTO_BASE_URL;
interface FormData {
email: string;
password: string;
name: string;
}
interface Tokens {
token: string;
refresh_token: string;
}
function SignUpPage() {
const [tempId, setTempId] = useState<string>("");
const [tokens, setTokens] = useState<Tokens | null>(null);
const [showConsent, setShowConsent] = useState(false);
const [formData, setFormData] = useState<FormData>({ email: "", password: "", name: "" });
const [consentGiven, setConsentGiven] = useState(false);
useEffect(() => {
// Generate temporary ID on mount
const id = `temp_${uuidv4()}`;
setTempId(id);
fetchTempToken(id);
}, []);
const fetchTempToken = async (id: string) => {
const response = await fetch("/api/consent/temp-token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ temp_id: id }),
});
const data = await response.json();
setTokens(data);
setShowConsent(true);
};
const handleConsentAccept = () => {
setConsentGiven(true);
setShowConsent(false);
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const response = await fetch("/api/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ...formData, temp_id: tempId }),
});
if (response.ok) {
// Registration complete, redirect to dashboard
window.location.href = "/dashboard";
}
};
return (
<div>
{/* Step 1: Show consent modal first */}
{showConsent && tokens && (
<RedactoNoticeConsent
noticeId={NOTICE_UUID!}
accessToken={tokens.token}
refreshToken={tokens.refresh_token}
baseUrl={REDACTO_BASE_URL}
onAccept={handleConsentAccept}
onDecline={() => {
// User declined - cannot proceed with registration
window.location.href = "/consent-required";
}}
onError={(error) => console.error("Consent error:", error)}
/>
)}
{/* Step 2: Show registration form after consent */}
{consentGiven && (
<form onSubmit={handleSubmit}>
<h1>Complete Your Registration</h1>
<input
type="email"
placeholder="Email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
required
/>
<input
type="password"
placeholder="Password"
value={formData.password}
onChange={(e) => setFormData({ ...formData, password: e.target.value })}
required
/>
<input
type="text"
placeholder="Full Name"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
required
/>
<button type="submit">Create Account</button>
</form>
)}
</div>
);
}
export default SignUpPage;User Log In
When an existing user logs in, authenticate them first, then let the SDK check if consent is valid or needs to be renewed.
Sequence Diagram
sequenceDiagram
participant U as User
participant F as Frontend
participant B as Your Backend
participant R as Redacto API
U->>F: Enter credentials
F->>B: POST /login
B->>B: Authenticate user
B->>R: POST /tokens/generate (org_user_id)
R-->>B: JWT tokens
B-->>F: Return user + tokens
F->>F: Render RedactoNoticeConsent with validateAgainst
Note over F,R: SDK checks consent status automatically
alt Consent needed/expired
F->>F: Show consent modal
U->>F: Accept consent
F->>R: Submit consent (via SDK)
R-->>F: Consent recorded
end
F-->>U: Login complete
Backend Code
import express, { Request, Response } from "express";
import axios from "axios";
const app = express();
app.use(express.json());
const CMS_API_KEY = process.env.CMS_API_KEY;
const REDACTO_BASE_URL = process.env.REDACTO_BASE_URL || "https://api.redacto.io";
const ORG_UUID = process.env.ORG_UUID;
const WORKSPACE_UUID = process.env.WORKSPACE_UUID;
app.post("/api/login", async (req: Request, res: Response) => {
const { email, password } = req.body;
try {
// 1. Authenticate user in your system
const user = await authenticateUser(email, password);
if (!user) {
res.status(401).json({ error: "Invalid credentials" });
return;
}
// 2. Generate tokens for the user
const tokenResponse = await axios.post(
`${REDACTO_BASE_URL}/consent/public/organisations/${ORG_UUID}/workspaces/${WORKSPACE_UUID}/tokens/generate`,
{ org_user_id: user.id },
{
headers: {
"X-CMS-API-Key": CMS_API_KEY,
"Content-Type": "application/json",
},
}
);
res.json({
user: { id: user.id, email: user.email, name: user.name },
token: tokenResponse.data.detail.token,
refresh_token: tokenResponse.data.detail.refresh_token,
});
} catch (error) {
console.error("Login error:", error);
res.status(500).json({ error: "Login failed" });
}
});
// Helper function (implement based on your auth system)
async function authenticateUser(email: string, password: string) {
// Your authentication logic here
// Returns user object or null if invalid
return { id: "user_123", email, name: "John Doe" };
}
app.listen(3000, () => console.log("Server running on port 3000"));Frontend Code
import { RedactoNoticeConsent } from "@redacto.io/consent-sdk-react";
import { useState } from "react";
const NOTICE_UUID = process.env.NEXT_PUBLIC_NOTICE_UUID;
const REDACTO_BASE_URL = process.env.NEXT_PUBLIC_REDACTO_BASE_URL;
interface Tokens {
token: string;
refresh_token: string;
}
interface User {
id: string;
email: string;
name: string;
}
function LoginPage() {
const [tokens, setTokens] = useState<Tokens | null>(null);
const [user, setUser] = useState<User | null>(null);
const [showConsent, setShowConsent] = useState(false);
const handleLogin = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const response = await fetch("/api/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
email: formData.get("email"),
password: formData.get("password"),
}),
});
if (!response.ok) {
alert("Login failed");
return;
}
const data = await response.json();
setUser(data.user);
setTokens({ token: data.token, refresh_token: data.refresh_token });
setShowConsent(true);
};
const handleConsentComplete = () => {
// Consent accepted or already valid
setShowConsent(false);
window.location.href = "/dashboard";
};
return (
<div>
<form onSubmit={handleLogin}>
<h1>Log In</h1>
<input name="email" type="email" placeholder="Email" required />
<input name="password" type="password" placeholder="Password" required />
<button type="submit">Log In</button>
</form>
{/* SDK checks consent status and shows modal only if needed */}
{showConsent && tokens && (
<RedactoNoticeConsent
noticeId={NOTICE_UUID!}
accessToken={tokens.token}
refreshToken={tokens.refresh_token}
baseUrl={REDACTO_BASE_URL}
validateAgainst="required"
onAccept={handleConsentComplete}
onDecline={() => {
// User declined - handle accordingly
window.location.href = "/consent-required";
}}
onError={(error) => {
// If error is because consent already exists, proceed
console.error("Consent error:", error);
handleConsentComplete();
}}
/>
)}
</div>
);
}
export default LoginPage;Consent on Anonymous IDs with Linking
Collect consent from anonymous visitors, then link to their real identity when they register or log in.
Sequence Diagram
sequenceDiagram
participant U as User
participant F as Frontend
participant B as Your Backend
participant R as Redacto API
Note over U,R: Phase 1: Anonymous Consent
U->>F: Visit site (anonymous)
F->>F: Generate anonymous ID (UUID)
F->>B: Request token for anon ID
B->>R: POST /tokens/generate (org_user_id: anon_xxx)
R-->>B: JWT tokens
B-->>F: Return tokens
F->>F: Show RedactoNoticeConsentInline
U->>F: Accept consent
F->>R: Submit consent (via SDK)
R-->>F: Consent recorded (anon user created)
Note over U,R: Phase 2: User Registers
U->>F: Fill registration form
F->>B: Submit with anon ID
B->>B: Create user in your system
B->>R: POST /consent-users/ (org_user_id: user_123)
R-->>B: User created
B->>R: POST /consent-users/link-users
Note right of B: primary: user_123<br/>alias: anon_xxx
R-->>B: Users linked
B-->>F: Registration complete
F-->>U: Continue with consent preserved
Backend Code
import express, { Request, Response } from "express";
import axios from "axios";
const app = express();
app.use(express.json());
const CMS_API_KEY = process.env.CMS_API_KEY;
const REDACTO_BASE_URL = process.env.REDACTO_BASE_URL || "https://api.redacto.io";
const ORG_UUID = process.env.ORG_UUID;
const WORKSPACE_UUID = process.env.WORKSPACE_UUID;
// Generate token for anonymous user
app.post("/api/consent/anonymous-token", async (req: Request, res: Response) => {
const { anonymous_id } = req.body;
if (!anonymous_id) {
res.status(400).json({ error: "anonymous_id is required" });
return;
}
try {
const response = await axios.post(
`${REDACTO_BASE_URL}/consent/public/organisations/${ORG_UUID}/workspaces/${WORKSPACE_UUID}/tokens/generate`,
{ org_user_id: anonymous_id },
{
headers: {
"X-CMS-API-Key": CMS_API_KEY,
"Content-Type": "application/json",
},
}
);
res.json({
token: response.data.detail.token,
refresh_token: response.data.detail.refresh_token,
});
} catch (error) {
console.error("Error generating token:", error);
res.status(500).json({ error: "Failed to generate token" });
}
});
// Register user and link anonymous consent
app.post("/api/register-with-anonymous", async (req: Request, res: Response) => {
const { email, password, name, anonymous_id } = req.body;
try {
// 1. Create user in your system
const user = await createUser({ email, password, name });
// 2. Create consent user in Redacto
await axios.post(
`${REDACTO_BASE_URL}/consent/organisations/${ORG_UUID}/workspaces/${WORKSPACE_UUID}/consent-ledger/consent-users/`,
{
org_user_id: user.id,
primary_email: email,
name: name,
},
{
headers: {
"X-CMS-API-Key": CMS_API_KEY,
"Content-Type": "application/json",
},
}
);
// 3. Link anonymous user to the new user
if (anonymous_id) {
await axios.post(
`${REDACTO_BASE_URL}/consent/organisations/${ORG_UUID}/workspaces/${WORKSPACE_UUID}/consent-ledger/consent-users/link-users`,
{
primary_org_user_id: user.id,
alias_org_user_ids: [anonymous_id],
},
{
headers: {
"X-CMS-API-Key": CMS_API_KEY,
"Content-Type": "application/json",
},
}
);
}
// 4. Generate new tokens for the registered user
const tokenResponse = await axios.post(
`${REDACTO_BASE_URL}/consent/public/organisations/${ORG_UUID}/workspaces/${WORKSPACE_UUID}/tokens/generate`,
{ org_user_id: user.id, email: email },
{
headers: {
"X-CMS-API-Key": CMS_API_KEY,
"Content-Type": "application/json",
},
}
);
res.json({
user: { id: user.id, email, name },
token: tokenResponse.data.detail.token,
refresh_token: tokenResponse.data.detail.refresh_token,
});
} catch (error) {
console.error("Registration error:", error);
res.status(500).json({ error: "Registration failed" });
}
});
// Helper function
async function createUser(data: { email: string; password: string; name: string }) {
return { id: `user_${Date.now()}`, ...data };
}
app.listen(3000, () => console.log("Server running on port 3000"));Frontend Code
import { RedactoNoticeConsentInline } from "@redacto.io/consent-sdk-react";
import { useState, useEffect } from "react";
import { v4 as uuidv4 } from "uuid";
const ORG_UUID = process.env.NEXT_PUBLIC_ORG_UUID;
const WORKSPACE_UUID = process.env.NEXT_PUBLIC_WORKSPACE_UUID;
const NOTICE_UUID = process.env.NEXT_PUBLIC_NOTICE_UUID;
const REDACTO_BASE_URL = process.env.NEXT_PUBLIC_REDACTO_BASE_URL;
interface Tokens {
accessToken: string | undefined;
refreshToken: string | undefined;
}
function LandingPage() {
const [anonymousId, setAnonymousId] = useState("");
const [tokens, setTokens] = useState<Tokens>({ accessToken: undefined, refreshToken: undefined });
const [consentGiven, setConsentGiven] = useState(false);
useEffect(() => {
// Generate or retrieve anonymous ID
let anonId = localStorage.getItem("anon_consent_id");
if (!anonId) {
anonId = `anon_${uuidv4()}`;
localStorage.setItem("anon_consent_id", anonId);
}
setAnonymousId(anonId);
fetchAnonymousToken(anonId);
}, []);
const fetchAnonymousToken = async (anonId: string) => {
const response = await fetch("/api/consent/anonymous-token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ anonymous_id: anonId }),
});
const data = await response.json();
setTokens({ accessToken: data.token, refreshToken: data.refresh_token });
};
const handleRegister = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const response = await fetch("/api/register-with-anonymous", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
email: formData.get("email"),
password: formData.get("password"),
name: formData.get("name"),
anonymous_id: anonymousId,
}),
});
if (response.ok) {
// Anonymous consent is now linked to the user
localStorage.removeItem("anon_consent_id");
window.location.href = "/dashboard";
}
};
return (
<div>
<h1>Welcome!</h1>
{/* Inline consent for anonymous users */}
<RedactoNoticeConsentInline
org_uuid={ORG_UUID!}
workspace_uuid={WORKSPACE_UUID!}
notice_uuid={NOTICE_UUID!}
accessToken={tokens.accessToken}
refreshToken={tokens.refreshToken}
baseUrl={REDACTO_BASE_URL}
onValidationChange={(valid) => setConsentGiven(valid)}
onAccept={() => console.log("Anonymous consent recorded")}
onError={(error) => console.error("Consent error:", error)}
/>
{/* Show registration form after consent */}
{consentGiven && (
<form onSubmit={handleRegister}>
<h2>Create an account to continue</h2>
<input name="email" type="email" placeholder="Email" required />
<input name="password" type="password" placeholder="Password" required />
<input name="name" type="text" placeholder="Name" required />
<button type="submit">Create Account</button>
</form>
)}
</div>
);
}
export default LandingPage;Consent from Multiple Channels with Linking
When users interact with your platform through different channels (web, mobile app, email), consolidate their consent records. Note that consent users are created when consent is submitted, not when tokens are generated.
Sequence Diagram
sequenceDiagram
participant W as Web User
participant M as Mobile User
participant B as Your Backend
participant R as Redacto API
Note over W,R: Channel 1: Web (Email identifier)
W->>B: Consent via web form
B->>R: POST /tokens/generate (email: [email protected])
R-->>B: Tokens
W->>R: Submit consent via SDK
R-->>W: Consent recorded (user created with email as org_user_id)
Note over M,R: Channel 2: Mobile App (Phone identifier)
M->>B: Consent via mobile app
B->>R: POST /tokens/generate (mobile: +1234567890)
R-->>B: Tokens
M->>R: Submit consent via SDK
R-->>M: Consent recorded (user created with phone as org_user_id)
Note over B,R: Channel 3: User identified as same person
B->>B: Detect same user across channels
B->>R: POST /consent-users/ (org_user_id: customer_123)
R-->>B: Primary user created
B->>R: POST /consent-users/link-users
Note right of B: primary: customer_123<br/>aliases: [email, phone]
R-->>B: All consent consolidated
Backend Code
import express, { Request, Response } from "express";
import axios, { AxiosError } from "axios";
const app = express();
app.use(express.json());
const CMS_API_KEY = process.env.CMS_API_KEY;
const REDACTO_BASE_URL = process.env.REDACTO_BASE_URL || "https://api.redacto.io";
const ORG_UUID = process.env.ORG_UUID;
const WORKSPACE_UUID = process.env.WORKSPACE_UUID;
interface LinkResult {
primary_user_uuid: string;
linked: string[];
already_linked: string[];
not_found: string[];
conflicts: Array<{
org_user_id: string;
existing_primary_org_user_id: string;
}>;
}
// When user is identified across channels
app.post("/api/consolidate-user", async (req: Request, res: Response) => {
const { user_id, email, phone } = req.body;
try {
// 1. Create the primary consent user with your system's ID
try {
await axios.post(
`${REDACTO_BASE_URL}/consent/organisations/${ORG_UUID}/workspaces/${WORKSPACE_UUID}/consent-ledger/consent-users/`,
{
org_user_id: user_id,
primary_email: email,
primary_mobile: phone,
},
{
headers: {
"X-CMS-API-Key": CMS_API_KEY,
"Content-Type": "application/json",
},
}
);
} catch (error) {
const axiosError = error as AxiosError;
// Handle 409 if user already exists - that's fine
if (axiosError.response?.status !== 409) {
throw error;
}
}
// 2. Build list of potential alias identifiers
// These are the org_user_ids that were created when consent was submitted
const aliasIds: string[] = [];
// When consent is submitted with just email, the email becomes the org_user_id
if (email) {
aliasIds.push(email);
}
// When consent is submitted with just phone, the phone becomes the org_user_id
if (phone) {
aliasIds.push(phone);
}
// 3. Link all aliases to the primary user
let linkResult: LinkResult | null = null;
if (aliasIds.length > 0) {
const linkResponse = await axios.post(
`${REDACTO_BASE_URL}/consent/organisations/${ORG_UUID}/workspaces/${WORKSPACE_UUID}/consent-ledger/consent-users/link-users`,
{
primary_org_user_id: user_id,
alias_org_user_ids: aliasIds,
},
{
headers: {
"X-CMS-API-Key": CMS_API_KEY,
"Content-Type": "application/json",
},
}
);
linkResult = linkResponse.data.detail;
console.log("Link results:", linkResult);
}
res.json({
success: true,
link_result: linkResult,
});
} catch (error) {
console.error("Consolidation error:", error);
res.status(500).json({ error: "Failed to consolidate user" });
}
});
app.listen(3000, () => console.log("Server running on port 3000"));Handling Link Results
interface LinkResult {
primary_user_uuid: string;
linked: string[];
already_linked: string[];
not_found: string[];
conflicts: Array<{
org_user_id: string;
existing_primary_org_user_id: string;
}>;
}
async function handleLinkResults(result: LinkResult): Promise<void> {
// Successfully linked
if (result.linked.length > 0) {
console.log(`Linked ${result.linked.length} users`);
}
// Already linked (idempotent, no action needed)
if (result.already_linked.length > 0) {
console.log(`${result.already_linked.length} already linked`);
}
// Not found - these users haven't given consent yet
// (consent submission creates users, not token generation)
if (result.not_found.length > 0) {
console.log(`${result.not_found.length} not found - no consent submitted yet`);
// Store for later linking when they do submit consent
await storeForLaterLinking(result.not_found);
}
// Conflicts - already linked to another primary
if (result.conflicts.length > 0) {
// May need manual review or different resolution strategy
for (const conflict of result.conflicts) {
console.warn(
`${conflict.org_user_id} already linked to ${conflict.existing_primary_org_user_id}`
);
}
}
}
async function storeForLaterLinking(identifiers: string[]): Promise<void> {
// Store identifiers to retry linking later
// Implementation depends on your system
}Use Case: CRM Integration
interface CRMCustomer {
crm_id: string;
email?: string;
phone?: string;
web_session_id?: string;
app_device_id?: string;
}
// When CRM identifies a customer across touchpoints
async function syncCustomerConsent(crmCustomer: CRMCustomer): Promise<void> {
const identifiers: string[] = [];
// Collect all known identifiers that may have been used for consent
if (crmCustomer.email) identifiers.push(crmCustomer.email);
if (crmCustomer.phone) identifiers.push(crmCustomer.phone);
if (crmCustomer.web_session_id) identifiers.push(crmCustomer.web_session_id);
if (crmCustomer.app_device_id) identifiers.push(crmCustomer.app_device_id);
// Create primary user with CRM ID
await createConsentUser({
org_user_id: crmCustomer.crm_id,
primary_email: crmCustomer.email,
primary_mobile: crmCustomer.phone,
metadata: { source: "crm_sync" },
});
// Link all identifiers
const result = await linkUsers({
primary_org_user_id: crmCustomer.crm_id,
alias_org_user_ids: identifiers,
});
// Handle results
await handleLinkResults(result);
// Now all consent from any channel is consolidated
}
// Helper functions (implement based on your setup)
async function createConsentUser(data: {
org_user_id: string;
primary_email?: string;
primary_mobile?: string;
metadata?: Record<string, unknown>;
}): Promise<void> {
// Call Redacto API to create user
}
async function linkUsers(data: {
primary_org_user_id: string;
alias_org_user_ids: string[];
}): Promise<LinkResult> {
// Call Redacto API to link users
return {} as LinkResult;
}Updated 9 days ago