Skip to main content

Endpoint

POST /v1/partner/handshake
Base URL: https://api.usesticker.com Staging/Sandbox URL: https://staging.api.usesticker.com

Description

Creates an authentication session for a user to access the embedded Sticker iframe. Returns a secure, time-limited session token and the iframe embed URL. Workflow:
  1. Partner authenticates with API key
  2. Partner provides internal_user_id or profile_id to identify the user
  3. Sticker finds the profile and validates it belongs to the partner
  4. Sticker generates a temporary session token (5 minute expiry, single-use)
  5. Returns session token + complete iframe embed URL

Authentication

Requires Partner API key in the X-API-Key header:
X-API-Key: sk_live_your_api_key_here

Request Body

You must provide either internal_user_id OR profile_id:
{
  "internal_user_id": "user-789"
}
OR
{
  "profile_id": "660f9500-f30c-52e5-b827-557766551111"
}

Request Parameters

internal_user_id
string
Your internal identifier for the user (provided during organization setup). Either this OR profile_id is required.
profile_id
string
Sticker’s unique identifier for the user profile (UUID). Either this OR internal_user_id is required.
Using internal_user_id is recommended as it uses your system’s identifiers and doesn’t require storing Sticker profile IDs.

Response

Success Response (200 OK)

{
  "success": true,
  "session_key": "a1b2c3d4e5f6789012345678901234567890123456789012345678901234",
  "iframe_embed_url": "https://shop.usesticker.com/embedded/550e8400-e29b-41d4-a716-446655440000?session_key=a1b2c3d4e5f6789012345678901234567890123456789012345678901234",
  "expires_at": "2024-01-15T10:35:00.000Z",
  "profile": {
    "id": "660f9500-f30c-52e5-b827-557766551111",
    "first_name": "Jane",
    "last_name": "Smith",
    "email": "jane@acmemedical.com"
  }
}

Response Fields

success
boolean
Whether the handshake succeeded.
session_key
string
Secure, time-limited token for authenticating the user in the iframe. 64-character hex string.
iframe_embed_url
string
Complete URL to embed in an iframe. Includes the partner ID and session key already appended.
expires_at
string
ISO 8601 timestamp when the session token expires. Tokens expire 5 minutes after generation.
profile
object
Basic profile information for the authenticated user.
profile.id
string
Sticker’s unique identifier for the profile (UUID).
profile.first_name
string
User’s first name.
profile.last_name
string
User’s last name.
profile.email
string
User’s email address.

Error Responses

{
  "error": "Invalid request body",
  "details": [
    {
      "code": "custom",
      "message": "Either internal_user_id or profile_id must be provided",
      "path": []
    }
  ]
}
Common causes:
  • Neither internal_user_id nor profile_id provided
  • Invalid UUID format for profile_id
{
  "error": "Unauthorized",
  "message": "Invalid or missing API key"
}
Solution: Check your API key is correct and included in the X-API-Key header.
{
  "error": "Profile not found",
  "details": "No profile found with the provided credentials for this partner"
}
Solution: Ensure the user was created via the organization setup endpoint first. Verify the internal_user_id or profile_id is correct.
{
  "error": "Profile not set up for authentication",
  "details": "Profile must be linked to an auth user. Please complete setup first."
}
Solution: The profile exists but is not properly linked to an auth user. Contact Sticker support.
{
  "error": "Failed to create authentication session",
  "details": "Database error message"
}
Solution: Retry with exponential backoff. Contact support if the error persists.

Session Token Properties

Session tokens have specific security properties:
PropertyDescription
Single-useInvalidated immediately after first use
Time-limitedExpires 5 minutes after generation
User-boundTied to a specific user profile
Partner-boundCan only be used with the partner’s iframe URL
Secure64-character cryptographically random hex string
Never reuse session tokens. Generate a new token each time the user opens the supplies module, even if they just closed it seconds ago.

Code Examples

async function getHandshakeToken(userId) {
  const response = await fetch('https://api.usesticker.com/v1/partner/handshake', {
    method: 'POST',
    headers: {
      'X-API-Key': process.env.STICKER_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      internal_user_id: userId
    })
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Handshake failed: ${error.error}`);
  }

  return await response.json();
}

// Usage
const { session_key, iframe_embed_url } = await getHandshakeToken('user-789');
console.log('Embed URL:', iframe_embed_url);

Using the Session Token

After receiving the handshake response, embed the iframe using the iframe_embed_url:
// React example
function SuppliesModule({ userId }) {
  const [iframeUrl, setIframeUrl] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function authenticate() {
      const response = await fetch('/api/supplies/auth', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ userId })
      });
      
      const { iframe_url } = await response.json();
      setIframeUrl(iframe_url);
      setLoading(false);
    }
    
    authenticate();
  }, [userId]);

  if (loading) return <div>Loading supplies...</div>;

  return (
    <iframe
      src={iframeUrl}
      className="w-full h-full border-0"
      title="Sticker Embedded Procurement"
      sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation"
      allow="payment; publickey-credentials-get; fullscreen"
    />
  );
}

Best Practices

Create session tokens only when the user clicks to open the supplies module. Don’t pre-generate tokens.
If the iframe fails to load (e.g., user’s connection is slow), generate a fresh token and retry.
Don’t store or cache session tokens. They’re single-use and short-lived.
Always call the handshake endpoint from your backend. Never expose your API key in client-side code.
If the handshake fails, show an error message and offer a retry button that generates a new token.