> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended**:
> ```bash
> npx @scalekit-inc/cli setup
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for 40+ agents.
> Features: full-stack-auth, agent-auth, mcp-auth, modular-sso, modular-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Set external IDs & metadata

Use your own identifiers and store custom fields for organizations and users to maintain data consistency across your systems
} from '@astrojs/starlight/components';

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.

   
   ### Node.js

```javascript title="Create organization with external ID"
// During user signup or organization creation
const { organization } = await scalekit.organization.createOrganization('Acme Corporation', {
  externalId: 'CUST-12345-ACME', // Your customer ID
});

// The Node.js SDK does not accept metadata at creation, so set it with a follow-up update
await scalekit.organization.updateOrganization(organization.id, {
  metadata: {
    plan_type: 'enterprise',
    billing_customer_id: 'stripe_cus_abc123',
  },
});

console.log('Organization created:', organization.id);
console.log('Your ID:', organization.externalId);
```

   ### Python

```python title="Create organization with external ID"
from scalekit.v1.organizations.organizations_pb2 import CreateOrganization

# During user signup or organization creation
organization = CreateOrganization(
    display_name='Acme Corporation',
    external_id='CUST-12345-ACME',  # Your customer ID
    metadata={
        'plan_type': 'enterprise',
        'billing_customer_id': 'stripe_cus_abc123'
    }
)
response = scalekit_client.organization.create_organization(organization=organization)
created_organization = response[0].organization

print(f'Organization created: {created_organization.id}')
print(f'Your ID: {created_organization.external_id}')
```

   ### Go

```go title="Create organization with external ID"
// During user signup or organization creation
resp, err := scalekitClient.Organization().CreateOrganization(ctx, "Acme Corporation", scalekit.CreateOrganizationOptions{
    ExternalId: "CUST-12345-ACME", // Your customer ID
    Metadata: map[string]string{
        "plan_type":           "enterprise",
        "billing_customer_id": "stripe_cus_abc123",
    },
})
if err != nil {
    log.Fatal(err)
}

org := resp.GetOrganization()
fmt.Printf("Organization created: %s\n", org.GetId())
fmt.Printf("Your ID: %s\n", org.GetExternalId())
```

   ### Java

```java title="Create organization with external ID"
// During user signup or organization creation
CreateOrganization createOrg = CreateOrganization.newBuilder()
    .setDisplayName("Acme Corporation")
    .setExternalId("CUST-12345-ACME") // Your customer ID
    .putMetadata("plan_type", "enterprise")
    .putMetadata("billing_customer_id", "stripe_cus_abc123")
    .build();

Organization organization = scalekitClient.organizations().create(createOrg);

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.

   
   ### Node.js

```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.getOrganizationByExternalId(customerId);

if (organization) {
  console.log('Found organization:', organization.displayName);
  // Update billing status, plan, etc.
  await updateCustomerBilling(organization.metadata.billing_customer_id);
}
```

   ### Python

```python title="Find organization by external ID"
# When processing a billing webhook or customer update
customer_id = 'CUST-12345-ACME'  # From your webhook payload

response = scalekit_client.organization.get_organization_by_external_id(customer_id)
organization = response[0].organization

if organization:
    print(f'Found organization: {organization.display_name}')
    # Update billing status, plan, etc.
    update_customer_billing(organization.metadata['billing_customer_id'])
```

   ### Go

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

resp, err := scalekitClient.Organization().GetOrganizationByExternalId(ctx, customerId)
if err != nil {
    log.Printf("Error finding organization: %v", err)
    return
}

org := resp.GetOrganization()
if org != nil {
    fmt.Printf("Found organization: %s\n", org.GetDisplayName())
    // Update billing status, plan, etc.
    billingId := org.GetMetadata()["billing_customer_id"]
    updateCustomerBilling(billingId)
}
```

   ### Java

```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 = scalekitClient.organizations().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.

   
   ### Node.js

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

console.log('External ID updated:', updatedOrg.externalId);
```

   ### Python

```python title="Update external ID"
from scalekit.v1.organizations.organizations_pb2 import UpdateOrganization

update_organization = UpdateOrganization(external_id='NEW-CUST-12345-ACME')
response = scalekit_client.organization.update_organization(
    organization_id=organization_id, organization=update_organization
)
updated_org = response[0].organization

print(f'External ID updated: {updated_org.external_id}')
```

   ### Go

```go title="Update external ID"
newExternalId := "NEW-CUST-12345-ACME"
resp, err := scalekitClient.Organization().UpdateOrganization(ctx, organizationId, &organizationsv1.UpdateOrganization{
    ExternalId: &newExternalId,
})
if err != nil {
    log.Fatal(err)
}

updatedOrg := resp.GetOrganization()
fmt.Printf("External ID updated: %s\n", updatedOrg.GetExternalId())
```

   ### Java

```java title="Update external ID"
UpdateOrganization updateOrg = UpdateOrganization.newBuilder()
    .setExternalId("NEW-CUST-12345-ACME")
    .build();

Organization updatedOrg = scalekitClient.organizations().updateById(organizationId, updateOrg);

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

### Node.js

```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

```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

```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

```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

### Node.js

```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

```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

```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

```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

### Node.js

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

### Python

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

### Go

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

### Java

```java title="Find user by external ID" wrap frame="terminal"
// Use case: Look up a Scalekit user when you have your own system's user ID
try {
    GetUserResponse response = scalekitClient.users()
        .getUserByExternalId("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());
}
```

> note: External ID method arguments
>
> User operations resolve a user from the external ID alone, so `getUserByExternalId`, `updateUserByExternalId`, and `deleteUserByExternalId` take only the external ID. Membership operations act on a user within an organization, so `createMembershipByExternalId`, `updateMembershipByExternalId`, and `deleteMembershipByExternalId` take both the organization ID and the external ID.

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 |
