// 01

What is Sam

Sam is an AI-powered PSA built for MSPs who want to run lean without cutting the important stuff.

Built by cybersecurity experts, Sam brings enterprise-grade detection and response to MSPs serving small business. It covers the full stack: a unified help desk across all accounts, around-the-clock security monitoring for Microsoft 365 and Google Workspace, automated daily backups, CIS Controls compliance tracking for every client, and AI-generated reports that go out without anyone having to write a word.

// 02

How Sam is Structured

Sam organizes everything around accounts. Every account is identified by its domain name. As an MSP, you have a root account and any number of customer accounts beneath it.

Your root account is the first thing you see when you log in. It's tied to your MSP's domain and is where you manage everything MSP-wide: your team, your RMM and expense management integrations, and a full view of every customer account you oversee.

Managed accounts represent each company you support. From your root account, you can delegate into any account with one click. Once inside, you're operating in that account's context — their monitors, their tickets, their compliance posture.

From your clients' perspective, Sam is simply their IT support. They reach it by email or text message. Sam triages, drafts a response, and pulls you in when a human touch is needed.

// 03

End User UX

From your clients' employees' perspective, Sam is simply their IT support. They don't need to learn a portal or install anything.

When you onboard a new client, you give their team two things: a phone number and an email address. That's it. End users can reach Sam by email or text message — whichever they prefer. Every interaction, regardless of channel, lands in the correct ticket queue in your admin dashboard and is tracked from first contact to resolution.

Sam responds to every inbound message within 30 seconds. That's the guaranteed SLA. The response is AI-generated and contextual — Sam reads the request, checks what it knows about the account, and replies with something useful rather than a generic acknowledgment. For the end user, it feels like reaching a real person immediately.

You can join any ticket at any point. If a situation needs a human, you step in alongside Sam's thread — the end user sees a seamless conversation and never has to repeat themselves. Sam handles the volume.

Want to try? Send an email to help@sam.pinkduckcompany.com and Sam will respond to you directly.

// 04

Getting Started

Follow these steps when onboarding a new account into Sam.

01
Your Root Account

When you first log into Sam, you see your root account. This is your MSP's home base, identified by your own domain. It's where you view managed accounts and configure global monitors.

Two global MSP monitors are:

Ramp (expense management). Connecting Ramp lets you create a virtual credit card for each managed account. When a card is used, the transaction is automatically associated with that account.

Level.io (RMM). Connecting Level.io gives Sam visibility into endpoints across all your accounts. Device alerts and policy violations automatically become tickets in the help desk.

02
Invite Your Clients

Enter the email address of any prospective customer and they'll receive an invitation to be managed. Once they accept, you can delegate into their account and start setting up their monitors.

03
Add Monitors

Delegate into a customer account from your root view, then open their Monitor screen. For every customer, connect at minimum their email platform and Cloudflare. Together they cover the two highest-risk vectors before anything else is configured.

From there, add any other SaaS products they use that Sam supports. The broader the integration coverage, the more useful Sam's alerts, reports, and compliance tracking become for that account.

04
Work the Help Desk

Once an account is connected, their employees can reach Sam immediately by email or text message. Tickets flow into your unified queue on the ticket board.

Sam handles first-contact AI responses automatically, sending replies and trying to separate signal from noise.

// 05

Advanced Features

These features are available within every account you manage. They turn Sam from a capable help desk into the backbone of how you deliver support and security.

// 05.1

Backups

Sam runs automatic differential backups every day for Microsoft 365, Google Workspace, and AWS EC2 across every account. Nothing to configure per client.

// 05.2

Compliance

Sam tracks all 18 CIS Controls for each account. You can create and customize policies to match a client's specific risk profile, and Sam monitors for drift continuously. When a gap opens up — a new user without MFA, an outdated policy, a misconfigured setting — Sam flags it without you having to run a manual review.

// 05.3

Reports

Sam maintains a continuous monthly report for every account. It covers ticket volume and resolution, security events, compliance posture, backup status, and expenses. An AI-written summary at the top gives you the key takeaways in plain language. Just copy-paste and email to your customer.

// 05.4

Notifications

Notifications let you broadcast a message when something affects the whole team. Internet down, scheduled maintenance, service outage — you send one message and the queue stays quiet.

// 05.5

Audit trail

Every action taken in Sam is logged and searchable. Who installed what, when was a ticket was closed and by who - all of it is captured and stored for 30+ days.

// 06

API docs

Sam exposes a REST API so you can embed Sam into your own tools. All endpoints return JSON.

// 06.1

About the API

All requests go to https://9vy0x0o0cc.execute-api.us-east-2.amazonaws.com.

Every endpoint returns JSON. API calls are scoped to your root MSP account by default. To operate inside a specific customer account, pass the account header with the customer's domain on any request.

// 06.2

Authentication

Sam uses AWS Cognito for authentication. Call exchange() with your credentials to get an API token, then pass it as a Bearer value in the Authorization header on every request. Tokens expire after one hour.

authentication.js JavaScript
async function exchange(userPoolId, clientId, email, password) {
  const region = userPoolId.split('_')[0];
  const resp = await fetch(`https://cognito-idp.${region}.amazonaws.com/`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-amz-json-1.1',
      'X-Amz-Target': 'AWSCognitoIdentityProviderService.InitiateAuth',
    },
    body: JSON.stringify({
      AuthFlow: 'USER_PASSWORD_AUTH',
      ClientId: clientId,
      AuthParameters: { USERNAME: email, PASSWORD: password },
    }),
  });
  const data = await resp.json();
  if (!resp.ok) throw new Error(data.message);
  return data.AuthenticationResult.IdToken;
}

const token = await exchange(
  'us-east-2_J5UAtrmqZ',       // User Pool ID
  'l988ndjcmbcfim10t25qehh1p',  // App Client ID
  'user@example.com',
  'password'
);
// 06.3

List Tickets

Returns tickets across every customer account your MSP manages — the same unified queue shown in the Help Desk screen. Filter by status with the status query parameter: O for open, C for closed.

msp.js JavaScript
const BASE = 'https://9vy0x0o0cc.execute-api.us-east-2.amazonaws.com';

// status=O for open, status=C for closed
const tickets = await fetch(`${BASE}/msp/ticket?status=O`, {
  headers: { 'Authorization': `Bearer ${token}` },
}).then(r => r.json());
// 06.4

Account Delegation

By default, every API call operates in the context of your root MSP account. To act on behalf of a customer, pass the account header set to their domain. Sam scopes all reads and writes to that account for any request that carries the header.

This example lists all tickets in a customer account, then fetches the update history for a specific ticket using the ID from the first response.

delegation.js JavaScript
const BASE = 'https://9vy0x0o0cc.execute-api.us-east-2.amazonaws.com';
const headers = {
  'Authorization': `Bearer ${token}`,
  'account': 'acmecorp.com',
};

// Step 1: List all tickets in the customer account
const tickets = await fetch(`${BASE}/ticket`, { headers }).then(r => r.json());

// Step 2: Fetch the update history for a specific ticket
const detail = await fetch(`${BASE}/ticket/${tickets[0].id}`, { headers }).then(r => r.json());
// 06.5

Create Tickets

Creating a ticket is a two-step process. First, POST to /ticket to create the record. Then POST to /ticket/{id} — using the ID from the first response — to add an opening touch. A touch is a threaded update on the ticket, like the first message in the conversation.

Set the account header on both calls to target a customer account.

create-ticket.js JavaScript
const BASE = 'https://9vy0x0o0cc.execute-api.us-east-2.amazonaws.com';
const headers = {
  'Authorization': `Bearer ${token}`,
  'Content-Type': 'application/json',
  'account': 'acmecorp.com',
};

// Step 1: Create the ticket
const ticket = await fetch(`${BASE}/ticket`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    name:    'Printer offline on 3rd floor',
    source:  'api',  // 'google' | 'microsoft' | 'api'
    service: 2,        // 1=Security Incident 2=Help Desk 3=Business Risk 4=Special Project
  }),
}).then(r => r.json());

// Step 2: Touch the ticket using the ID from the previous response
const touch = await fetch(`${BASE}/ticket/${ticket.id}`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    value: 'The HP LaserJet in the east wing is not responding. Tried power cycling — no change.',
    user:  'jane@acmecorp.com',
  }),
}).then(r => r.json());