> **Building with AI coding agents?** If you're using an AI coding agent, install the official Scalekit plugin. It gives your agent full awareness of the Scalekit API — reducing hallucinations and enabling faster, more accurate code generation.
>
> - **Claude Code**: `/plugin marketplace add scalekit-inc/claude-code-authstack` then `/plugin install <auth-type>@scalekit-auth-stack`
> - **GitHub Copilot CLI**: `copilot plugin marketplace add scalekit-inc/github-copilot-authstack` then `copilot plugin install <auth-type>@scalekit-auth-stack`
> - **Codex**: run the bash installer, restart, then open Plugin Directory and enable `<auth-type>`
> - **Skills CLI** (Windsurf, Cline, 40+ agents): `npx skills add scalekit-inc/skills --list` then `--skill <skill-name>`
>
> `<auth-type>` / `<skill-name>`: `agent-auth`, `full-stack-auth`, `mcp-auth`, `modular-sso`, `modular-scim` — [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Set external IDs & metadata

After setting up authentication and creating organizations and users, you'll often need to connect them with your existing systems. This guide shows you how to use external IDs and metadata to integrate both organizations and users with your billing platform, CRM, HR systems, or other infrastructure while storing additional custom information.

Use these features to:

- **Link existing systems** - Connect organizations and users to customer records in your billing platform, CRM, HR systems, or database
- **Store custom data** - Add billing details, feature flags, plan information, user attributes, or internal tracking data
- **Maintain data consistency** - Keep your existing identifiers while leveraging Scalekit's organization and user features
- **Simplify integration** - Avoid complex ID mapping between your systems and Scalekit

## Organization external IDs for system integration

External IDs let you identify organizations using your own identifiers instead of Scalekit's generated IDs. This is essential when migrating from existing systems or integrating with multiple platforms.

1. ### Set external IDs during organization creation

   Include your system's identifier when creating organizations to maintain consistent references across your infrastructure.

   ```javascript title="Create organization with external ID" {3,9}
   // During user signup or organization creation
   const organization = await scalekit.organization.create({
     display_name: 'Acme Corporation',
     external_id: 'CUST-12345-ACME', // Your customer ID
     metadata: {
       plan_type: 'enterprise',
       billing_customer_id: 'stripe_cus_abc123'
     }
   });

   console.log('Organization created:', organization.id);
   console.log('Your ID:', organization.external_id);
   ```
   ```python title="Create organization with external ID" {3,9}
   # During user signup or organization creation
   organization = scalekit.organization.create({
       'display_name': 'Acme Corporation',
       'external_id': 'CUST-12345-ACME',  # Your customer ID
       'metadata': {
           'plan_type': 'enterprise',
           'billing_customer_id': 'stripe_cus_abc123'
       }
   })

   print(f'Organization created: {organization.id}')
   print(f'Your ID: {organization.external_id}')
   ```
   ```go title="Create organization with external ID" {3,11}
   // During user signup or organization creation
   org, err := scalekit.Organization.Create(OrganizationCreateOptions{
       DisplayName: "Acme Corporation",
       ExternalId:  "CUST-12345-ACME", // Your customer ID
       Metadata: map[string]interface{}{
           "plan_type":             "enterprise",
           "billing_customer_id":   "stripe_cus_abc123",
       },
   })

   if err != nil {
       log.Fatal(err)
   }

   fmt.Printf("Organization created: %s\n", org.Id)
   fmt.Printf("Your ID: %s\n", org.ExternalId)
   ```
   ```java title="Create organization with external ID" {5,12}
   // During user signup or organization creation
   Map<String, Object> metadata = Map.of(
       "plan_type", "enterprise",
       "billing_customer_id", "stripe_cus_abc123"
   );

   Organization organization = scalekit.organization().create(
       "Acme Corporation",
       "CUST-12345-ACME", // Your customer ID
       metadata
   );

   System.out.println("Organization created: " + organization.getId());
   System.out.println("Your ID: " + organization.getExternalId());
   ```
2. ### Find organizations using your IDs

   Use external IDs to quickly locate organizations when processing webhooks, handling customer support requests, or syncing data between systems.

   ```javascript title="Find organization by external ID"
   // When processing a billing webhook or customer update
   const customerId = 'CUST-12345-ACME'; // From your webhook payload

   const organization = await scalekit.organization.getByExternalId(customerId);

   if (organization) {
     console.log('Found organization:', organization.display_name);
     // Update billing status, plan, etc.
     await updateCustomerBilling(organization.metadata.billing_customer_id);
   }
   ```
   ```python title="Find organization by external ID"
   # When processing a billing webhook or customer update
   customer_id = 'CUST-12345-ACME'  # From your webhook payload

   organization = scalekit.organization.get_by_external_id(customer_id)

   if organization:
       print(f'Found organization: {organization.display_name}')
       # Update billing status, plan, etc.
       await update_customer_billing(organization.metadata['billing_customer_id'])
   ```
   ```go title="Find organization by external ID"
   // When processing a billing webhook or customer update
   customerId := "CUST-12345-ACME" // From your webhook payload

   org, err := scalekit.Organization.GetByExternalId(customerId)
   if err != nil {
       log.Printf("Error finding organization: %v", err)
       return
   }

   if org != nil {
       fmt.Printf("Found organization: %s\n", org.DisplayName)
       // Update billing status, plan, etc.
       billingId := org.Metadata["billing_customer_id"].(string)
       updateCustomerBilling(billingId)
   }
   ```
   ```java title="Find organization by external ID"
   // When processing a billing webhook or customer update
   String customerId = "CUST-12345-ACME"; // From your webhook payload

   Organization organization = scalekit.organization().getByExternalId(customerId);

   if (organization != null) {
       System.out.println("Found organization: " + organization.getDisplayName());
       // Update billing status, plan, etc.
       String billingId = (String) organization.getMetadata().get("billing_customer_id");
       updateCustomerBilling(billingId);
   }
   ```
3. ### Update external IDs when needed

   If your customer IDs change or you need to migrate identifier formats, you can update external IDs for existing organizations.

   ```javascript title="Update external ID"
   const updatedOrg = await scalekit.organization.update(organizationId, {
     external_id: 'NEW-CUST-12345-ACME'
   });

   console.log('External ID updated:', updatedOrg.external_id);
   ```
   ```python title="Update external ID"
   updated_org = scalekit.organization.update(organization_id, {
       'external_id': 'NEW-CUST-12345-ACME'
   })

   print(f'External ID updated: {updated_org.external_id}')
   ```
   ```go title="Update external ID"
   updatedOrg, err := scalekit.Organization.Update(organizationId, OrganizationUpdateOptions{
       ExternalId: "NEW-CUST-12345-ACME",
   })

   fmt.Printf("External ID updated: %s\n", updatedOrg.ExternalId)
   ```
   ```java title="Update external ID"
   Organization updatedOrg = scalekit.organization().update(organizationId, Map.of(
       "external_id", "NEW-CUST-12345-ACME"
   ));

   System.out.println("External ID updated: " + updatedOrg.getExternalId());
   ```
   ## User external IDs and metadata

Just as organizations need external identifiers, users often require integration with existing systems. User external IDs and metadata work similarly to organization identifiers, enabling you to link Scalekit users with your CRM, HR systems, and other business applications.

### When to use user external IDs and metadata

<div>
**External IDs** link Scalekit users to your existing systems:
- Reference users in your database, CRM, or billing system
- Maintain consistent user identification across multiple platforms
- Enable easy data synchronization and lookups
</div>

<div>
**Metadata** stores additional user attributes:
- Organizational information (department, location, role level)
- Business context (territory, quota, access permissions)
- Integration data (external system IDs, custom properties)
</div>

### Set user external IDs and metadata during user creation

```javascript title="Create user with external ID and metadata" wrap frame="terminal" ins={4-12}
// Use case: Create user during system migration or bulk import with existing system references
const { user } = await scalekit.user.createUserAndMembership("<organizationId>", {
  email: "john.doe@company.com",
  externalId: "SALESFORCE-003921",
  metadata: {
    department: "Sales",
    employeeId: "EMP-002",
    territory: "West Coast",
    quota: 150000,
    crmAccountId: "ACC-789",
    hubspotContactId: "12345",
  },
  userProfile: {
    firstName: "John",
    lastName: "Doe",
  },
  sendInvitationEmail: true,
});
```

```python title="Create user with external ID and metadata" wrap frame="terminal" ins={4-12}
# Use case: Create user during system migration or bulk import with existing system references
user_response = scalekit.user.create_user_and_membership(
    "<organization_id>",
    email="john.doe@company.com",
    external_id="SALESFORCE-003921",
    metadata={
        "department": "Sales",
        "employee_id": "EMP-002",
        "territory": "West Coast",
        "quota": 150000,
        "crm_account_id": "ACC-789",
        "hubspot_contact_id": "12345"
    },
    user_profile={
        "first_name": "John",
        "last_name": "Doe"
    },
    send_invitation_email=True
)
```

```go title="Create user with external ID and metadata" wrap frame="terminal" ins={4-12}
// Use case: Create user during system migration or bulk import with existing system references
newUser := &usersv1.CreateUser{
    Email: "john.doe@company.com",
    ExternalId: "SALESFORCE-003921",
    Metadata: map[string]string{
        "department":          "Sales",
        "employee_id":         "EMP-002",
        "territory":           "West Coast",
        "quota":               "150000",
        "crm_account_id":      "ACC-789",
        "hubspot_contact_id":  "12345",
    },
    UserProfile: &usersv1.CreateUserProfile{
        FirstName: "John",
        LastName:  "Doe",
    },
}
userResp, err := scalekitClient.User().CreateUserAndMembership(
    ctx,
    "<organizationId>",
    newUser,
    true, // sendInvitationEmail
)
```

```java title="Create user with external ID and metadata" wrap frame="terminal" ins={4-12}
// Use case: Create user during system migration or bulk import with existing system references
CreateUser createUser = CreateUser.newBuilder()
    .setEmail("john.doe@company.com")
    .setExternalId("SALESFORCE-003921")
    .putMetadata("department", "Sales")
    .putMetadata("employee_id", "EMP-002")
    .putMetadata("territory", "West Coast")
    .putMetadata("quota", "150000")
    .putMetadata("crm_account_id", "ACC-789")
    .putMetadata("hubspot_contact_id", "12345")
    .setUserProfile(
        CreateUserProfile.newBuilder()
            .setFirstName("John")
            .setLastName("Doe")
            .build())
    .build();

CreateUserAndMembershipRequest createUserReq = CreateUserAndMembershipRequest.newBuilder()
    .setUser(createUser)
    .setSendInvitationEmail(true)
    .build();

CreateUserAndMembershipResponse userResp = scalekitClient.users()
    .createUserAndMembership("<organizationId>", createUserReq);
```

### Update user external IDs and metadata for existing users

```javascript title="Update user external ID and metadata" wrap frame="terminal" ins={3-11}
// Use case: Link user with external systems (CRM, HR) and track custom attributes in a single call
const updatedUser = await scalekit.user.updateUser("<userId>", {
  externalId: "SALESFORCE-003921",
  metadata: {
    department: "Sales",
    employeeId: "EMP-002",
    territory: "West Coast",
    quota: 150000,
    crmAccountId: "ACC-789",
    hubspotContactId: "12345",
  },
});
```

```python title="Update user external ID and metadata" wrap frame="terminal" ins={3-11}
# Use case: Link user with external systems (CRM, HR) and track custom attributes in a single call
updated_user = scalekit.user.update_user(
    "<user_id>",
    external_id="SALESFORCE-003921",
    metadata={
        "department": "Sales",
        "employee_id": "EMP-002",
        "territory": "West Coast",
        "quota": 150000,
        "crm_account_id": "ACC-789",
        "hubspot_contact_id": "12345"
    }
)
```

```go title="Update user external ID and metadata" frame="terminal"
// Use case: Link user with external systems (CRM, HR) and track custom attributes in a single call
updateUser := &usersv1.UpdateUser{
    ExternalId: "SALESFORCE-003921",
    Metadata: map[string]string{
        "department":          "Sales",
        "employee_id":         "EMP-002",
        "territory":           "West Coast",
        "quota":               "150000",
        "crm_account_id":      "ACC-789",
        "hubspot_contact_id":  "12345",
    },
}
updatedUser, err := scalekitClient.User().UpdateUser(
    ctx,
    "<userId>",
    updateUser,
)
```

```java title="Update user external ID and metadata" frame="terminal" "setExternalId" "putMetadata"
// Use case: Link user with external systems (CRM, HR) and track custom attributes in a single call
UpdateUser updateUser = UpdateUser.newBuilder()
    .setExternalId("SALESFORCE-003921")
    .putMetadata("department", "Sales")
    .putMetadata("employee_id", "EMP-002")
    .putMetadata("territory", "West Coast")
    .putMetadata("quota", "150000")
    .putMetadata("crm_account_id", "ACC-789")
    .putMetadata("hubspot_contact_id", "12345")
    .build();

UpdateUserRequest updateReq = UpdateUserRequest.newBuilder()
    .setUser(updateUser)
    .build();

User updatedUser = scalekitClient.users().updateUser("<userId>", updateReq);
```

### Find users by external ID

```javascript title="Find user by external ID" wrap frame="terminal"
// Use case: Look up Scalekit user when you have your system's user ID
const user = await scalekit.user.getUserByExternalId("<organizationId>", "SALESFORCE-003921");
console.log(`Found user: ${user.email} with ID: ${user.id}`);
```

```python title="Find user by external ID" wrap frame="terminal"
# Use case: Look up Scalekit user when you have your system's user ID
user = scalekit.user.get_user_by_external_id("<organization_id>", "SALESFORCE-003921")
print(f"Found user: {user['email']} with ID: {user['id']}")
```

```go title="Find user by external ID" wrap frame="terminal"
// Use case: Look up Scalekit user when you have your system's user ID
user, err := scalekitClient.User().GetUserByExternalId(
    ctx,
    "<organizationId>",
    "SALESFORCE-003921",
)
if err != nil {
    log.Printf("User not found: %v", err)
} else {
    fmt.Printf("Found user: %s with ID: %s\n", user.Email, user.Id)
}
```

```java title="Find user by external ID" wrap frame="terminal"
// Use case: Look up Scalekit user when you have your system's user ID
try {
    GetUserByExternalIdResponse response = scalekitClient.users()
        .getUserByExternalId("<organizationId>", "SALESFORCE-003921");

    User user = response.getUser();
    System.out.printf("Found user: %s with ID: %s%n", user.getEmail(), user.getId());
} catch (Exception e) {
    System.err.println("User not found: " + e.getMessage());
}
```

This integration approach maintains consistent user identity across your system architecture while letting you choose the source of truth for authentication and authorization. Both user and organization external IDs work together to provide complete system integration capabilities.

---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
