# Create an SSO connection

> Source: https://elaichi.ai/docs/api-reference/sso-connections/sso-connection/createssoconnection/

`POST /sso-connection`

Resource: **Sso Connection** · API: **SSO connections**

## Request body

- **`protocol`** _(string)_
  Immutable after creation.
  Allowed: `oidc`, `saml`
- **`name`** _(string)_
- **`is_active`** _(boolean)_
- **`enforced`** _(boolean)_
  See `enforced` on the response — this locks users to the IdP.
- **`is_default`** _(boolean)_
- **`config`** _(object)_
  Protocol-specific IdP settings. Never contains secrets — the OIDC client secret is write-only.
  - **`idp_entity_id`** _(string)_
    SAML: IdP entity id.
  - **`idp_sso_url`** _(string)_
    SAML: IdP single sign-on URL.
  - **`idp_x509_cert`** _(string)_
    SAML: IdP signing certificate (PEM).
  - **`idp_metadata_xml`** _(string)_
    SAML: paste IdP metadata to populate the fields above. Accepted on write; never returned.
  - **`issuer`** _(string)_
    OIDC: issuer URL.
  - **`client_id`** _(string)_
    OIDC: relying-party client id.
  - **`discovery_url`** _(string)_
    OIDC: discovery document URL.
  - **`sign_authn_requests`** _(boolean)_
    SAML: sign SP-initiated AuthnRequests.
  - **`allow_idp_initiated`** _(boolean)_
    SAML: accept unsolicited IdP-initiated responses. Rejected by default.
- **`client_secret`** _(string)_
  OIDC client secret. Write-only — stored encrypted, never returned.
- **`default_role_id`** _(string,null)_
  Role id (`role_…`).

## Response body

- **`id`** _(string)_
  SSO connection id (`sso_…`).
- **`organization_id`** _(string)_
  Owning organization (`org_…`).
- **`protocol`** _(string)_
  Allowed: `oidc`, `saml`
- **`name`** _(string)_
- **`is_active`** _(boolean)_
  A draft may be saved incomplete, but cannot be activated until the protocol's required fields are present.
- **`enforced`** _(boolean)_
  When enforced, users on the connection's verified domains can ONLY sign in through this IdP — social login and email codes are refused for them.
- **`is_default`** _(boolean)_
  The connection domain resolution picks when a domain has several.
- **`config`** _(object)_
  Protocol-specific IdP settings. Never contains secrets — the OIDC client secret is write-only.
  - **`idp_entity_id`** _(string)_
    SAML: IdP entity id.
  - **`idp_sso_url`** _(string)_
    SAML: IdP single sign-on URL.
  - **`idp_x509_cert`** _(string)_
    SAML: IdP signing certificate (PEM).
  - **`idp_metadata_xml`** _(string)_
    SAML: paste IdP metadata to populate the fields above. Accepted on write; never returned.
  - **`issuer`** _(string)_
    OIDC: issuer URL.
  - **`client_id`** _(string)_
    OIDC: relying-party client id.
  - **`discovery_url`** _(string)_
    OIDC: discovery document URL.
  - **`sign_authn_requests`** _(boolean)_
    SAML: sign SP-initiated AuthnRequests.
  - **`allow_idp_initiated`** _(boolean)_
    SAML: accept unsolicited IdP-initiated responses. Rejected by default.
- **`default_role_id`** _(string,null)_
  Role (`role_…`) explicitly configured for users provisioned through this connection, or null to track the default. Org Owner is refused here. Read `effective_default_role_id` to learn what a JIT login actually grants.
- **`effective_default_role_id`** _(string,null)_
  Server-computed: the role SSO just-in-time provisioning through this connection really grants. Equals `default_role_id` when that is set and the role still exists; otherwise the **Member** system role, which is what the join falls back to both when nothing is configured and when the configured role has since been deleted. `null` means even that fallback is missing, so auto-provisioning through this connection is broken and the first login seats nobody.
- **`has_client_secret`** _(boolean)_
  Whether an OIDC client secret is stored. The secret itself is never returned.
- **`urls`** _(object)_
  The protocol URLs to hand to the IdP administrator (ACS / metadata / callback, by protocol).
- **`created_at`** _(string)_
- **`updated_at`** _(string)_

## Code examples

### curl

```bash
curl -X POST 'https://api.elaichi.ai/sso-connection' \
  -H 'Authorization: Bearer $ELAICHI_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"protocol":"oidc","name":"your_name","is_active":true,"enforced":true,"is_default":true,"config":{},"client_secret":"your_client_secret"}'
```

### JavaScript

```javascript
const body = {
  "protocol": "oidc",
  "name": "your_name",
  "is_active": true,
  "enforced": true,
  "is_default": true,
  "config": {},
  "client_secret": "your_client_secret"
};

const response = await fetch('https://api.elaichi.ai/sso-connection', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ' + process.env.ELAICHI_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(body),
});

const data = await response.json();
console.log(data);
```

### Python

```python
import os
import requests

url = "https://api.elaichi.ai/sso-connection"
headers = {
    "Authorization": f"Bearer {os.environ['ELAICHI_API_TOKEN']}",
    "Content-Type": "application/json",
}
payload = {
    "protocol": "oidc",
    "name": "your_name",
    "is_active": True,
    "enforced": True,
    "is_default": True,
    "config": {},
    "client_secret": "your_client_secret"
}

response = requests.post(url, headers=headers, json=payload)
print(response.json())
```
