Description
When using createInvitationBulk with publicMetadata, the metadata is not transferred to the Clerk user object after the invitee accepts the invitation and completes signup. The docs state:
Once an invitee accepts and completes signup, these metadata will end up in the user's public metadata.
This does not happen in practice.
Steps to reproduce
- Create bulk invitations with
publicMetadata:
const client = await clerkClient()
await client.invitations.createInvitationBulk([
{
emailAddress: '[email protected]',
publicMetadata: { role: 'agent' },
redirectUrl: 'https://example.com/admin',
ignoreExisting: true
}
])
- Invitee receives the email and completes signup
- Check the created user's
publicMetadata — it is empty ({})
Expected behavior
The user's publicMetadata should contain { role: 'agent' } after signup, as documented.
SDK investigation
Verified the SDK serialization is correct. In @clerk/backend, createInvitationBulk passes bodyParams through the standard snakecase_keys formatter:
// InvitationAPI
async createInvitationBulk(params) {
return this.request({
method: "POST",
path: joinPaths(basePath, "bulk"),
bodyParams: params // no options override
});
}
// buildRequest serializer
const formatKeys = (object) => snakecase_keys(object, { deep: false });
body: JSON.stringify(Array.isArray(bodyParams) ? bodyParams.map(formatKeys) : formatKeys(bodyParams))
The top-level keys are correctly converted (publicMetadata → public_metadata), and the nested metadata object ({ role: 'agent' }) doesn't require any conversion. The request body sent to the API is valid.
This suggests the issue is server-side — the bulk endpoint accepts public_metadata but does not propagate it to the user created after the invitation is accepted.
Workaround
Explicitly set publicMetadata via updateUserMetadata in the user.created webhook handler:
await clerkClient.users.updateUserMetadata(userId, {
publicMetadata: { role: 'agent' }
})
Environment
@clerk/nextjs: 6.39.0
@clerk/backend: 2.33.0
- Node.js: 22
- Tested with 2 separate invitees, both had empty
publicMetadata after signup
Description
When using
createInvitationBulkwithpublicMetadata, the metadata is not transferred to the Clerk user object after the invitee accepts the invitation and completes signup. The docs state:This does not happen in practice.
Steps to reproduce
publicMetadata:publicMetadata— it is empty ({})Expected behavior
The user's
publicMetadatashould contain{ role: 'agent' }after signup, as documented.SDK investigation
Verified the SDK serialization is correct. In
@clerk/backend,createInvitationBulkpassesbodyParamsthrough the standardsnakecase_keysformatter:The top-level keys are correctly converted (
publicMetadata→public_metadata), and the nested metadata object ({ role: 'agent' }) doesn't require any conversion. The request body sent to the API is valid.This suggests the issue is server-side — the bulk endpoint accepts
public_metadatabut does not propagate it to the user created after the invitation is accepted.Workaround
Explicitly set
publicMetadataviaupdateUserMetadatain theuser.createdwebhook handler:Environment
@clerk/nextjs: 6.39.0@clerk/backend: 2.33.0publicMetadataafter signup