# ServiceLogin

*ServiceLogin* is the setting that lets a *Space* sign up and log in the end-users (*ServiceUser*) of its own product through OAuth. It is the entry point for attaching to your product an identity system that is separate from a Weegloo platform account (the Weegloo User who logs in to the content studio). A member who signs up through this setting receives *ServiceLogin*'s default role (`defaultRole`), and that member's token authenticates against ACMA/ACDA.

A *Space* has at most one *ServiceLogin*. If you call create (`POST`) again when one already exists, the request is rejected. That is why the read also fetches that single one with `GET .../service-login`, without a `loginId` (there is no list endpoint).

## Resource structure {#resource-structure}

The following is the response for one *ServiceLogin*. Together with `sys` (system properties), it has the body properties that hold the service display info and sign-up behavior: `name`, `callbackUrl`, `contactEmail`, and `approvalRequired`.

```json
{
  "sys": {
    "id": "3trmXRM3RqbgSnifyg7PSlgn01Ex",
    "type": "ServiceLogin",
    "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
    "defaultRole": { "sys": { "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp", "type": "Refer", "targetType": "ServiceUserRole" } },
    "providers": [
      { "registrationId": "google", "clientId": "821047-dailywear.apps.googleusercontent.com" }
    ],
    "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
    "createdAt": "2026-06-18T12:55:00.000Z",
    "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
    "updatedAt": "2026-06-18T12:55:00.000Z",
    "version": 1
  },
  "name": "DailyWear membership",
  "callbackUrl": "https://dailywear.example/auth/callback",
  "contactEmail": "members@dailywear.example",
  "approvalRequired": false
}
```

Key properties:

- `defaultRole`: The `Refer` to the *ServiceUserRole* that a newly signed-up member receives by default. When a member needs a different role, override it with the *ServiceUser*'s `roleOverride`.
- `providers`: The list of OAuth providers this service supports. Each item consists of `registrationId`, `clientId`, and `clientSecret`. `clientSecret` does not appear in the response.
- `callbackUrl`: The URL a member is sent to after finishing OAuth login. An exchange token (`exchangeToken`) comes back attached to this URL as a query string.
- `approvalRequired`: When turned on, a new member signs up with login disabled (`enableLogin=false`) and needs administrator approval.

## System properties (sys) {#system-properties-sys}

Every *ServiceLogin* carries common system properties in the `sys` object. `space`, `defaultRole`, `createdBy`, and `updatedBy` are in the `Refer` shape (`{ "sys": { "id", "type": "Refer", "targetType" } }`).

| Property | Type | Description |
|---|---|---|
| `id` | string | Unique resource identifier. |
| `type` | string | Resource kind. For a *ServiceLogin* this is always `"ServiceLogin"`. |
| `space` | Refer&lt;Space&gt; | The *Space* this setting belongs to. |
| `defaultRole` | Refer&lt;ServiceUserRole&gt; | The *ServiceUserRole* that a newly signed-up member receives by default. |
| `providers` | Provider array | The list of supported OAuth providers. Response items do not include `clientSecret`. |
| `createdBy` | Refer&lt;User&gt; | The Weegloo User who created this setting. |
| `createdAt` | string (date-time) | Creation time. |
| `updatedBy` | Refer&lt;User&gt; | The Weegloo User who last updated it. |
| `updatedAt` | string (date-time) | Last update time. |
| `version` | integer | The resource version. You put it in the `X-Weegloo-Version` header when updating. |

Because *ServiceLogin* is a setting resource, it has no publishing concept. There is no `publish`, `archive`, or `status`, only a `version` to prevent concurrent-update conflicts.

## Body properties and providers {#body-properties-and-providers}

| Property | Type | Description |
|---|---|---|
| `name` | string | The service display name. |
| `callbackUrl` | string | The URL to go to after OAuth login completes. `exchangeToken` comes back attached to this URL as a query string. |
| `contactEmail` | string | The contact email for the service administrator. |
| `approvalRequired` | boolean | When `true`, a new member starts with `enableLogin=false` and needs administrator approval. The default is `false`. |

### providers {#providers}

`providers` is the list of OAuth providers this service supports. Each provider consists of these three values.

| Property | Type | Description |
|---|---|---|
| `registrationId` | string | The OAuth provider identifier. Currently `google`, `github`, `facebook`, `gitlab`, `kakao`, `naver`, and `line` are supported. |
| `clientId` | string | The client ID issued by that provider. |
| `clientSecret` | string | The client secret issued by that provider. It is write-only, so it does not appear in the response. |

The `registrationId` values for which WEEGLOO currently has OAuth endpoints wired up are seven: `google`, `github`, `facebook`, `gitlab`, `kakao`, `naver`, and `line`. Login does not work with any other value.

You can put providers into the *ServiceLogin* create body together, or manage them separately with the provider add, update, and delete endpoints below. The *ServiceLogin* update (`PUT`) body has no `providers`, so you handle the providers of an already-created setting with the dedicated endpoints.

A *ServiceLogin* must always have at least one provider, and can have at most 10. On create, you must put at least one into `providers`. The last remaining provider cannot be deleted, and attempting to delete it is rejected. To remove all providers, delete the *ServiceLogin* itself.

### Registering the redirect URI {#redirect-uri}

When you create an OAuth app in each provider's console (Google, GitHub, Facebook, GitLab, Kakao, Naver, LINE), you must register the **authorized redirect URI** (redirect URI) with exactly the same value that WEEGLOO uses. If the value differs, login fails with `redirect_uri mismatch`.

The URI to register has this format.

`https://auth.weegloo.com/v1/spaces/{spaceId}/login/oauth2/code/{registrationId}`

- `{spaceId}`: The `sys.id` of the *Space* this *ServiceLogin* belongs to.
- `{registrationId}`: The provider identifier (`google`, `github`, `facebook`, `gitlab`, `kakao`, `naver`, `line`).

For example, to attach Google to the *Space* `HnQ32YiH`, you register `https://auth.weegloo.com/v1/spaces/HnQ32YiH/login/oauth2/code/google`.

## Errors {#errors}

These are the codes you meet when working with a *ServiceLogin*. For codes that are common to every resource, see [common errors](/api/reference/common/errors.md).

| Code | Condition |
|---|---|
| `WGL409003` | The caller called create (`POST`) again while that *Space* already had a *ServiceLogin*. Adding a provider with a `registrationId` that is already registered is rejected with the same code. |
| `WGL422055` | The caller tried to delete the last remaining provider on a *ServiceLogin*. |

## API {#api}

The base URL for all endpoints below is `https://cma.weegloo.com/v1`, and a Bearer token that authenticates against CMA is required in the `Authorization` header. The update endpoints (`PUT`, `PATCH`) and the provider management endpoints must carry the current `sys.version` in the `X-Weegloo-Version` header to prevent concurrent-update conflicts. Create and *ServiceLogin* delete do not have this header. The read fetches that Space's single *ServiceLogin* without a `loginId`.

```api-endpoint
{
  "title": "Read the ServiceLogin",
  "method": "GET",
  "path": "/spaces/{spaceId}/service-login",
  "description": "Reads that Space's single ServiceLogin. Because only one exists per Space, you read it as a single resource without a loginId (this is not a list endpoint). Use include to expand related resources.",
  "responseStatus": 200,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true }
  },
  "queryParameterSchema": {
    "include": { "type": "integer", "description": "Related-resource inclusion level. 0=default, 1=related resources, 2=nested relations, 3=full", "default": 0 }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRM3RqbgSnifyg7PSlgn01Ex",
      "type": "ServiceLogin",
      "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
      "defaultRole": { "sys": { "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp", "type": "Refer", "targetType": "ServiceUserRole" } },
      "providers": [
        { "registrationId": "google", "clientId": "821047-dailywear.apps.googleusercontent.com" }
      ],
      "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-06-18T12:55:00.000Z",
      "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-06-18T12:55:00.000Z",
      "version": 1
    },
    "name": "DailyWear membership",
    "callbackUrl": "https://dailywear.example/auth/callback",
    "contactEmail": "members@dailywear.example",
    "approvalRequired": false
  }
}
```

```api-endpoint
{
  "title": "Create a ServiceLogin",
  "method": "POST",
  "path": "/spaces/{spaceId}/service-login",
  "description": "Creates a ServiceLogin setting on a Space. Because a Space has only one ServiceLogin, if one already exists the request is rejected. You can include providers in the body. clientSecret is write-only, so it does not appear in the response.",
  "responseStatus": 201,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" }
  },
  "requestBodySchema": {
    "type": "object",
    "required": ["name", "callbackUrl", "contactEmail", "defaultRole", "providers", "approvalRequired"],
    "properties": {
      "name": { "type": "string", "description": "The service display name" },
      "callbackUrl": { "type": "string", "description": "The URL to go to after OAuth login completes. exchangeToken is attached as a query string." },
      "contactEmail": { "type": "string", "description": "The contact email for the service administrator" },
      "approvalRequired": { "type": "boolean", "description": "When true, a new member starts with enableLogin=false and needs administrator approval. Default false." },
      "defaultRole": { "type": "object", "description": "The Refer to the ServiceUserRole that a new member receives by default" },
      "providers": {
        "type": "array",
        "description": "The list of supported OAuth providers. At least 1, at most 10.",
        "minItems": 1,
        "maxItems": 10,
        "items": {
          "type": "object",
          "required": ["registrationId", "clientId", "clientSecret"],
          "properties": {
            "registrationId": { "type": "string", "description": "The OAuth provider identifier (for example, google)" },
            "clientId": { "type": "string", "description": "The client ID issued by the provider" },
            "clientSecret": { "type": "string", "description": "The client secret issued by the provider (write-only, excluded from the response)" }
          }
        }
      }
    },
    "example": {
      "name": "DailyWear membership",
      "callbackUrl": "https://dailywear.example/auth/callback",
      "contactEmail": "members@dailywear.example",
      "approvalRequired": false,
      "defaultRole": { "sys": { "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp", "type": "Refer", "targetType": "ServiceUserRole" } },
      "providers": [
        { "registrationId": "google", "clientId": "821047-dailywear.apps.googleusercontent.com", "clientSecret": "<client secret>" }
      ]
    }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRM3RqbgSnifyg7PSlgn01Ex",
      "type": "ServiceLogin",
      "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
      "defaultRole": { "sys": { "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp", "type": "Refer", "targetType": "ServiceUserRole" } },
      "providers": [
        { "registrationId": "google", "clientId": "821047-dailywear.apps.googleusercontent.com" }
      ],
      "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-06-18T12:55:00.000Z",
      "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-06-18T12:55:00.000Z",
      "version": 1
    },
    "name": "DailyWear membership",
    "callbackUrl": "https://dailywear.example/auth/callback",
    "contactEmail": "members@dailywear.example",
    "approvalRequired": false
  }
}
```

```api-endpoint
{
  "title": "Update a ServiceLogin",
  "method": "PUT",
  "path": "/spaces/{spaceId}/service-login/{loginId}",
  "description": "Replaces a ServiceLogin's name, callbackUrl, contactEmail, defaultRole, and approvalRequired. providers is not in this body and is managed with the dedicated provider endpoints. You must carry the current sys.version in the X-Weegloo-Version header.",
  "responseStatus": 200,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "loginId": { "type": "string", "description": "The sys.id of the ServiceLogin", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" },
    "X-Weegloo-Version": { "type": "string", "description": "The current sys.version of the resource to update (prevents concurrent-update conflicts)" }
  },
  "requestBodySchema": {
    "type": "object",
    "required": ["name", "callbackUrl", "contactEmail", "defaultRole", "approvalRequired"],
    "properties": {
      "name": { "type": "string", "description": "The service display name" },
      "callbackUrl": { "type": "string", "description": "The URL to go to after OAuth login completes" },
      "contactEmail": { "type": "string", "description": "The contact email for the service administrator" },
      "approvalRequired": { "type": "boolean", "description": "When true, a new member starts with enableLogin=false and needs administrator approval" },
      "defaultRole": { "type": "object", "description": "The Refer to the ServiceUserRole that a new member receives by default" }
    },
    "example": {
      "name": "DailyWear membership",
      "callbackUrl": "https://dailywear.example/auth/callback",
      "contactEmail": "cs@dailywear.example",
      "approvalRequired": true,
      "defaultRole": { "sys": { "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp", "type": "Refer", "targetType": "ServiceUserRole" } }
    }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRM3RqbgSnifyg7PSlgn01Ex",
      "type": "ServiceLogin",
      "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
      "defaultRole": { "sys": { "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp", "type": "Refer", "targetType": "ServiceUserRole" } },
      "providers": [
        { "registrationId": "google", "clientId": "821047-dailywear.apps.googleusercontent.com" }
      ],
      "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-06-18T12:55:00.000Z",
      "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-06-18T12:56:00.000Z",
      "version": 2
    },
    "name": "DailyWear membership",
    "callbackUrl": "https://dailywear.example/auth/callback",
    "contactEmail": "cs@dailywear.example",
    "approvalRequired": true
  }
}
```

```api-endpoint
{
  "title": "Partially update a ServiceLogin (JSON Patch)",
  "method": "PATCH",
  "path": "/spaces/{spaceId}/service-login/{loginId}",
  "description": "Updates only part of a ServiceLogin with RFC 6902 JSON Patch. The request Content-Type header must be application/json-patch+json. You must carry the current sys.version in the X-Weegloo-Version header.",
  "responseStatus": 200,
  "baseUrl": "https://cma.weegloo.com/v1",
  "requestContentType": "application/json-patch+json",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "loginId": { "type": "string", "description": "The sys.id of the ServiceLogin", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" },
    "X-Weegloo-Version": { "type": "string", "description": "The current sys.version of the resource to update (prevents concurrent-update conflicts)" },
    "Content-Type": { "type": "string", "description": "application/json-patch+json (RFC 6902 JSON Patch)" }
  },
  "requestBodySchema": {
    "type": "array",
    "description": "An array of RFC 6902 JSON Patch operations (op / path / value / from). path is an RFC 6901 JSON Pointer.",
    "items": {
      "type": "object",
      "required": ["op", "path"],
      "properties": {
        "op": { "type": "string", "enum": ["add", "remove", "replace", "move", "copy", "test"], "description": "Operation kind" },
        "path": { "type": "string", "description": "Target location (JSON Pointer). Example: /approvalRequired" },
        "value": { "description": "The value used by add/replace/test" },
        "from": { "type": "string", "description": "The source location for move/copy" }
      }
    },
    "example": [
      { "op": "replace", "path": "/approvalRequired", "value": true }
    ]
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRM3RqbgSnifyg7PSlgn01Ex",
      "type": "ServiceLogin",
      "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
      "defaultRole": { "sys": { "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp", "type": "Refer", "targetType": "ServiceUserRole" } },
      "providers": [
        { "registrationId": "google", "clientId": "821047-dailywear.apps.googleusercontent.com" }
      ],
      "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-06-18T12:55:00.000Z",
      "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-06-18T12:57:00.000Z",
      "version": 3
    },
    "name": "DailyWear membership",
    "callbackUrl": "https://dailywear.example/auth/callback",
    "contactEmail": "members@dailywear.example",
    "approvalRequired": true
  }
}
```

```api-endpoint
{
  "title": "Delete a ServiceLogin",
  "method": "DELETE",
  "path": "/spaces/{spaceId}/service-login/{loginId}",
  "description": "Deletes the ServiceLogin setting. Responds with 204 and no body.",
  "responseStatus": 204,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "loginId": { "type": "string", "description": "The sys.id of the ServiceLogin", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" }
  }
}
```

```api-endpoint
{
  "title": "Add a provider",
  "method": "PUT",
  "path": "/spaces/{spaceId}/service-login/{loginId}/providers",
  "description": "Adds an OAuth provider to a ServiceLogin. registrationId, clientId, and clientSecret are all required. You must carry the current sys.version in the X-Weegloo-Version header. clientSecret is write-only, so it does not appear in the response.",
  "responseStatus": 200,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "loginId": { "type": "string", "description": "The sys.id of the ServiceLogin", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" },
    "X-Weegloo-Version": { "type": "string", "description": "The current sys.version of the resource to update (prevents concurrent-update conflicts)" }
  },
  "requestBodySchema": {
    "type": "object",
    "required": ["registrationId", "clientId", "clientSecret"],
    "properties": {
      "registrationId": { "type": "string", "description": "The OAuth provider identifier (for example, github)" },
      "clientId": { "type": "string", "description": "The client ID issued by the provider" },
      "clientSecret": { "type": "string", "description": "The client secret issued by the provider (write-only, excluded from the response)" }
    },
    "example": {
      "registrationId": "github",
      "clientId": "Iv1.dailywear-github",
      "clientSecret": "<client secret>"
    }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRM3RqbgSnifyg7PSlgn01Ex",
      "type": "ServiceLogin",
      "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
      "defaultRole": { "sys": { "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp", "type": "Refer", "targetType": "ServiceUserRole" } },
      "providers": [
        { "registrationId": "google", "clientId": "821047-dailywear.apps.googleusercontent.com" },
        { "registrationId": "github", "clientId": "Iv1.dailywear-github" }
      ],
      "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-06-18T12:55:00.000Z",
      "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-06-18T12:58:00.000Z",
      "version": 2
    },
    "name": "DailyWear membership",
    "callbackUrl": "https://dailywear.example/auth/callback",
    "contactEmail": "members@dailywear.example",
    "approvalRequired": false
  }
}
```

```api-endpoint
{
  "title": "Update a provider",
  "method": "PUT",
  "path": "/spaces/{spaceId}/service-login/{loginId}/providers/{registrationId}",
  "description": "Replaces the clientId and clientSecret of the provider specified by registrationId. registrationId is specified in the path, so it is not in the body. You must carry the current sys.version in the X-Weegloo-Version header. clientSecret is write-only, so it does not appear in the response.",
  "responseStatus": 200,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "loginId": { "type": "string", "description": "The sys.id of the ServiceLogin", "required": true },
    "registrationId": { "type": "string", "description": "The registrationId of the provider to update (for example, google)", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" },
    "X-Weegloo-Version": { "type": "string", "description": "The current sys.version of the resource to update (prevents concurrent-update conflicts)" }
  },
  "requestBodySchema": {
    "type": "object",
    "required": ["clientId", "clientSecret"],
    "properties": {
      "clientId": { "type": "string", "description": "The client ID issued by the provider" },
      "clientSecret": { "type": "string", "description": "The client secret issued by the provider (write-only, excluded from the response)" }
    },
    "example": {
      "clientId": "821047-dailywear-v2.apps.googleusercontent.com",
      "clientSecret": "<client secret>"
    }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRM3RqbgSnifyg7PSlgn01Ex",
      "type": "ServiceLogin",
      "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
      "defaultRole": { "sys": { "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp", "type": "Refer", "targetType": "ServiceUserRole" } },
      "providers": [
        { "registrationId": "google", "clientId": "821047-dailywear-v2.apps.googleusercontent.com" }
      ],
      "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-06-18T12:55:00.000Z",
      "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-06-18T12:59:00.000Z",
      "version": 3
    },
    "name": "DailyWear membership",
    "callbackUrl": "https://dailywear.example/auth/callback",
    "contactEmail": "members@dailywear.example",
    "approvalRequired": false
  }
}
```

```api-endpoint
{
  "title": "Delete a provider",
  "method": "DELETE",
  "path": "/spaces/{spaceId}/service-login/{loginId}/providers/{registrationId}",
  "description": "Deletes the provider specified by registrationId. This delete returns 200, not 204, and the response body contains the updated ServiceLogin. Because a ServiceLogin must keep at least one provider, attempting to delete the last remaining provider is rejected. You must carry the current sys.version in the X-Weegloo-Version header.",
  "responseStatus": 200,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "loginId": { "type": "string", "description": "The sys.id of the ServiceLogin", "required": true },
    "registrationId": { "type": "string", "description": "The registrationId of the provider to delete (for example, google)", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" },
    "X-Weegloo-Version": { "type": "string", "description": "The current sys.version of the resource to update (prevents concurrent-update conflicts)" }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRM3RqbgSnifyg7PSlgn01Ex",
      "type": "ServiceLogin",
      "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
      "defaultRole": { "sys": { "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp", "type": "Refer", "targetType": "ServiceUserRole" } },
      "providers": [],
      "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-06-18T12:55:00.000Z",
      "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-06-18T13:00:00.000Z",
      "version": 4
    },
    "name": "DailyWear membership",
    "callbackUrl": "https://dailywear.example/auth/callback",
    "contactEmail": "members@dailywear.example",
    "approvalRequired": false
  }
}
```

## Related documents {#related-documents}

- [ServiceUserRole](/api/reference/cma/service-user-role.md): The permission bundle to give via `defaultRole`.
- [ServiceUser](/api/reference/cma/service-user.md): A member who signed up through this setting.
- [Auth API](/api/reference/auth-api.md): The member OAuth login and token-exchange flow.
