---
title: Identity Provider Initiated SSO
description: You can start an identity provider initiated SAML single sign-on authentication session through a GET request. The GET /{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}} operation starts the sign-on flow.
component: pingone-api
page_id: pingone-api:auth:saml-2.0/identity-provider-initiated-sso
canonical_url: https://developer.pingidentity.com/pingone-api/auth/saml-2.0/identity-provider-initiated-sso.html
section_ids:
  example-request: Example Request
---

# Identity Provider Initiated SSO

##

```none
GET {{authPath}}/{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}}
```

You can start an identity provider initiated SAML single sign-on authentication session through a `GET` request. The `GET /{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}}` operation starts the sign-on flow.

The request URL includes the service provider's entity ID property (`spEntityId`) and the application's URL property (`applicationUrl`) as parameters in the request.

The `applicationUrl` parameter overrides the `defaultTargetUrl` request parameter (refer to [Applications SAML settings data model](../../platform/applications/applications-1.html#applications-saml-settings-data-model)) that is used to set the RelayState value passed as a deep link to the application. Although `applicationUrl` is generally a URL, because it's used as deep link, this is not enforced.

Include the optional `flowPolicyId` query parameter to indicate the desired PingOne authentication policy by its name or the ID of the DaVinci flow policy that PingOne should use to authenticate the user. The specified policy must be added to the application (refer to [Create SOP Assignment](../../platform/applications/application-sign-on-policy-assignments/create-sop-assignment.html) for authentication policies or [Create an Application Flow Policy Assignment](../../platform/applications/application-flow-policy-assignments/create-flow-policy-assignment.html) for DaVinci flow policies). If omitted, the flow uses the authentication policy logic described in [Application Flow Policy Assignments](../../platform/applications/application-flow-policy-assignments.html).

> **Collapse: Query parameters**
>
> | Parameter        | Description                                                                                                                      |
> | ---------------- | -------------------------------------------------------------------------------------------------------------------------------- |
> | `applicationUrl` | The application's URL.                                                                                                           |
> | `flowPolicyId`   | The ID of the DaVinci flow policy that is used to authenticate the user or the name of a PingOne authentication policy.          |
> | `spEntityId`     | The service provider entity ID used to lookup the application. This is a required property and is unique within the environment. |
>
> Refer to [SAML data model](../saml-2.0.html#saml-data-model) for complete descriptions.

##

### Example Request

* cURL

* C#

* Go

* HTTP

* Java

* jQuery

* NodeJS

* Python

* PHP

* Ruby

* Swift

```shell
curl --location --globoff '{{authPath}}/{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}}'
```

```csharp
var options = new RestClientOptions("{{authPath}}/{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}}")
{
  MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("", Method.Get);
RestResponse response = await client.ExecuteAsync(request);
Console.WriteLine(response.Content);
```

```golang
package main

import (
  "fmt"
  "net/http"
  "io"
)

func main() {

  url := "{{authPath}}/{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}}"
  method := "GET"

  client := &http.Client {
  }
  req, err := http.NewRequest(method, url, nil)

  if err != nil {
    fmt.Println(err)
    return
  }
  res, err := client.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer res.Body.Close()

  body, err := io.ReadAll(res.Body)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(string(body))
}
```

```http
GET /{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}} HTTP/1.1
Host: {{authPath}}
```

```java
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = RequestBody.create(mediaType, "");
Request request = new Request.Builder()
  .url("{{authPath}}/{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}}")
  .method("GET", body)
  .build();
Response response = client.newCall(request).execute();
```

```javascript
var settings = {
  "url": "{{authPath}}/{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}}",
  "method": "GET",
  "timeout": 0,
};

$.ajax(settings).done(function (response) {
  console.log(response);
});
```

```javascript
var request = require('request');
var options = {
  'method': 'GET',
  'url': '{{authPath}}/{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}}',
  'headers': {
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
```

```python
import requests

url = "{{authPath}}/{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}}"

payload = {}
headers = {}

response = requests.request("GET", url, headers=headers, data=payload)

print(response.text)
```

```php
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('{{authPath}}/{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}}');
$request->setMethod(HTTP_Request2::METHOD_GET);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
try {
  $response = $request->send();
  if ($response->getStatus() == 200) {
    echo $response->getBody();
  }
  else {
    echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
    $response->getReasonPhrase();
  }
}
catch(HTTP_Request2_Exception $e) {
  echo 'Error: ' . $e->getMessage();
}
```

```ruby
require "uri"
require "net/http"

url = URI("{{authPath}}/{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}}")

http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
```

```swift
var request = URLRequest(url: URL(string: "{{authPath}}/{{envID}}/saml20/idp/startsso?spEntityId={{spEntityIdValue}}&applicationUrl={{appUrl}}")!,timeoutInterval: Double.infinity)
request.httpMethod = "GET"

let task = URLSession.shared.dataTask(with: request) { data, response, error in
  guard let data = data else {
    print(String(describing: error))
    return
  }
  print(String(data: data, encoding: .utf8)!)
}

task.resume()
```
