Skip to main content
Use integrations when the credential belongs to the signed-in app user. Use secrets when the credential belongs to the app operator or workspace.

OAuth integrations

app.add_integration(
    cpsl.GitHub(
        client_id=cpsl.Secret.from_name("GITHUB_CLIENT_ID"),
        client_secret=cpsl.Secret.from_name("GITHUB_CLIENT_SECRET"),
        scopes=["repo", "read:user"],
    )
)
Store the OAuth client credentials as workspace secrets.

Secret-form integrations

app.add_integration(cpsl.AWS())
app.add_integration(cpsl.Tailscale())
Known secret-form integrations infer the fields the user needs to provide.

Prompt from chat

@app.message()
async def handle(session: cpsl.Session, msg: cpsl.Message):
    creds = await session.require_integration(
        cpsl.Integration.GITHUB,
        reason="Connect GitHub so I can inspect repositories.",
    )
    await session.reply(f"Connected GitHub with scopes: {creds.scopes}")

Show a non-blocking card

await session.show_integration(
    cpsl.Integration.GITHUB,
    reason="Connect GitHub to unlock project analysis.",
)

Use integrations in pages

@app.data("repos", access="authenticated")
async def repos(ctx: cpsl.RequestContext):
    github = ctx.integrations.get(cpsl.Integration.GITHUB)
    if not github:
        return {"connected": False, "repos": []}

    return {"connected": True, "repos": await load_repos(github.access_token)}
Pages can use this response to render the workflow or ask the user to connect the missing service.