curl --request POST \
--url https://api.staging.payrails.io/auth/sso/connections \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: <content-type>' \
--header 'x-idempotency-key: <x-idempotency-key>' \
--data '
{
"type": "SAML",
"provider": "okta",
"metadata": {
"saml": {
"samlMetadataURL": "https://sso.okta.com/saml2/metadata/xyzx123yz"
}
}
}
'import requests
url = "https://api.staging.payrails.io/auth/sso/connections"
payload = {
"type": "SAML",
"provider": "okta",
"metadata": { "saml": { "samlMetadataURL": "https://sso.okta.com/saml2/metadata/xyzx123yz" } }
}
headers = {
"x-idempotency-key": "<x-idempotency-key>",
"Content-Type": "<content-type>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-idempotency-key': '<x-idempotency-key>',
'Content-Type': '<content-type>',
Authorization: 'Bearer <token>'
},
body: JSON.stringify({
type: 'SAML',
provider: 'okta',
metadata: {saml: {samlMetadataURL: 'https://sso.okta.com/saml2/metadata/xyzx123yz'}}
})
};
fetch('https://api.staging.payrails.io/auth/sso/connections', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.staging.payrails.io/auth/sso/connections",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'type' => 'SAML',
'provider' => 'okta',
'metadata' => [
'saml' => [
'samlMetadataURL' => 'https://sso.okta.com/saml2/metadata/xyzx123yz'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: <content-type>",
"x-idempotency-key: <x-idempotency-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.staging.payrails.io/auth/sso/connections"
payload := strings.NewReader("{\n \"type\": \"SAML\",\n \"provider\": \"okta\",\n \"metadata\": {\n \"saml\": {\n \"samlMetadataURL\": \"https://sso.okta.com/saml2/metadata/xyzx123yz\"\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-idempotency-key", "<x-idempotency-key>")
req.Header.Add("Content-Type", "<content-type>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.staging.payrails.io/auth/sso/connections")
.header("x-idempotency-key", "<x-idempotency-key>")
.header("Content-Type", "<content-type>")
.header("Authorization", "Bearer <token>")
.body("{\n \"type\": \"SAML\",\n \"provider\": \"okta\",\n \"metadata\": {\n \"saml\": {\n \"samlMetadataURL\": \"https://sso.okta.com/saml2/metadata/xyzx123yz\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.staging.payrails.io/auth/sso/connections")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-idempotency-key"] = '<x-idempotency-key>'
request["Content-Type"] = '<content-type>'
request["Authorization"] = 'Bearer <token>'
request.body = "{\n \"type\": \"SAML\",\n \"provider\": \"okta\",\n \"metadata\": {\n \"saml\": {\n \"samlMetadataURL\": \"https://sso.okta.com/saml2/metadata/xyzx123yz\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "88c9db51-4dbf-4ee0-9a9c-1f9fd2f6d0ef",
"reference": "saml-connection-123",
"type": "SAML",
"status": "enabled",
"metadata": {
"saml": {
"samlMetadataURL": "https://sso.okta.com/app/exk123/sso/saml/metadata",
"rawSamlMetadataXMLString": "<xml>...</xml>"
}
},
"name": "payrails-saml-okta",
"displayName": "payrails-saml-okta",
"provider": "okta",
"createdAt": "2024-07-12T10:23:45Z",
"updatedAt": "2024-07-12T10:35:02Z"
}{
"errors": [
{
"id": "a24bc325-3929-4d9d-9c08-b3aa532685b7",
"code": "request.malformed",
"detail": "The request has malformed syntax",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#requestmalformed"
}
]
}{
"errors": [
{
"id": "a24bc325-3929-4d9d-9c08-b3aa532685b7",
"code": "request.unauthorized",
"detail": "The request lacks necessary credentials to perform the specified action",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#requestunauthorized"
}
]
}{
"errors": [
{
"id": "e7db22b3-914e-4975-928e-9edfb0885bea",
"code": "request.forbidden",
"detail": "The request credentials lack the required permissions to perform the specified action",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#requestforbidden"
}
]
}{
"errors": [
{
"id": "673f020f-5435-4408-b7ab-0cdabfc51ed6",
"title": "Not Acceptable.",
"detail": "Your request doesn't specify the API version. Your request `Content-Type` header MUST point to an existing API version.",
"code": ""
}
]
}{
"errors": [
{
"id": "a24bc325-3929-4d9d-9c08-b3aa532685b7",
"code": "request.conflict",
"detail": "The request operation is not allowed due to a conflict with the current state of the resource",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#requestconflict"
}
]
}{
"errors": [
{
"id": "07a1d642-dbf5-47d3-8563-700514b38e46",
"title": "Unsupported Media Type.",
"detail": "The request header `Content-Type: application/json` is not supported. All requests content type headers MUST be set to `application/json`.",
"code": ""
}
]
}{
"errors": [
{
"id": "07a1d642-dbf5-47d3-8563-700514b38e46",
"code": "request.header.missing",
"detail": "The request is missing a required header",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#requestheadermissing"
}
]
}{
"errors": [
{
"id": "a24bc325-3929-4d9d-9c08-b3aa532685b7",
"code": "request.rate-limit",
"detail": "Too many requests",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#requestrate-limit"
}
]
}{
"errors": [
{
"id": "a24bc325-3929-4d9d-9c08-b3aa532685b7",
"code": "internal",
"detail": "An internal error occurred",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#internal"
}
]
}Create SSO connection
Create a new SSO identity provider connection.
curl --request POST \
--url https://api.staging.payrails.io/auth/sso/connections \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: <content-type>' \
--header 'x-idempotency-key: <x-idempotency-key>' \
--data '
{
"type": "SAML",
"provider": "okta",
"metadata": {
"saml": {
"samlMetadataURL": "https://sso.okta.com/saml2/metadata/xyzx123yz"
}
}
}
'import requests
url = "https://api.staging.payrails.io/auth/sso/connections"
payload = {
"type": "SAML",
"provider": "okta",
"metadata": { "saml": { "samlMetadataURL": "https://sso.okta.com/saml2/metadata/xyzx123yz" } }
}
headers = {
"x-idempotency-key": "<x-idempotency-key>",
"Content-Type": "<content-type>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-idempotency-key': '<x-idempotency-key>',
'Content-Type': '<content-type>',
Authorization: 'Bearer <token>'
},
body: JSON.stringify({
type: 'SAML',
provider: 'okta',
metadata: {saml: {samlMetadataURL: 'https://sso.okta.com/saml2/metadata/xyzx123yz'}}
})
};
fetch('https://api.staging.payrails.io/auth/sso/connections', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.staging.payrails.io/auth/sso/connections",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'type' => 'SAML',
'provider' => 'okta',
'metadata' => [
'saml' => [
'samlMetadataURL' => 'https://sso.okta.com/saml2/metadata/xyzx123yz'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: <content-type>",
"x-idempotency-key: <x-idempotency-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.staging.payrails.io/auth/sso/connections"
payload := strings.NewReader("{\n \"type\": \"SAML\",\n \"provider\": \"okta\",\n \"metadata\": {\n \"saml\": {\n \"samlMetadataURL\": \"https://sso.okta.com/saml2/metadata/xyzx123yz\"\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-idempotency-key", "<x-idempotency-key>")
req.Header.Add("Content-Type", "<content-type>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.staging.payrails.io/auth/sso/connections")
.header("x-idempotency-key", "<x-idempotency-key>")
.header("Content-Type", "<content-type>")
.header("Authorization", "Bearer <token>")
.body("{\n \"type\": \"SAML\",\n \"provider\": \"okta\",\n \"metadata\": {\n \"saml\": {\n \"samlMetadataURL\": \"https://sso.okta.com/saml2/metadata/xyzx123yz\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.staging.payrails.io/auth/sso/connections")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-idempotency-key"] = '<x-idempotency-key>'
request["Content-Type"] = '<content-type>'
request["Authorization"] = 'Bearer <token>'
request.body = "{\n \"type\": \"SAML\",\n \"provider\": \"okta\",\n \"metadata\": {\n \"saml\": {\n \"samlMetadataURL\": \"https://sso.okta.com/saml2/metadata/xyzx123yz\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "88c9db51-4dbf-4ee0-9a9c-1f9fd2f6d0ef",
"reference": "saml-connection-123",
"type": "SAML",
"status": "enabled",
"metadata": {
"saml": {
"samlMetadataURL": "https://sso.okta.com/app/exk123/sso/saml/metadata",
"rawSamlMetadataXMLString": "<xml>...</xml>"
}
},
"name": "payrails-saml-okta",
"displayName": "payrails-saml-okta",
"provider": "okta",
"createdAt": "2024-07-12T10:23:45Z",
"updatedAt": "2024-07-12T10:35:02Z"
}{
"errors": [
{
"id": "a24bc325-3929-4d9d-9c08-b3aa532685b7",
"code": "request.malformed",
"detail": "The request has malformed syntax",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#requestmalformed"
}
]
}{
"errors": [
{
"id": "a24bc325-3929-4d9d-9c08-b3aa532685b7",
"code": "request.unauthorized",
"detail": "The request lacks necessary credentials to perform the specified action",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#requestunauthorized"
}
]
}{
"errors": [
{
"id": "e7db22b3-914e-4975-928e-9edfb0885bea",
"code": "request.forbidden",
"detail": "The request credentials lack the required permissions to perform the specified action",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#requestforbidden"
}
]
}{
"errors": [
{
"id": "673f020f-5435-4408-b7ab-0cdabfc51ed6",
"title": "Not Acceptable.",
"detail": "Your request doesn't specify the API version. Your request `Content-Type` header MUST point to an existing API version.",
"code": ""
}
]
}{
"errors": [
{
"id": "a24bc325-3929-4d9d-9c08-b3aa532685b7",
"code": "request.conflict",
"detail": "The request operation is not allowed due to a conflict with the current state of the resource",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#requestconflict"
}
]
}{
"errors": [
{
"id": "07a1d642-dbf5-47d3-8563-700514b38e46",
"title": "Unsupported Media Type.",
"detail": "The request header `Content-Type: application/json` is not supported. All requests content type headers MUST be set to `application/json`.",
"code": ""
}
]
}{
"errors": [
{
"id": "07a1d642-dbf5-47d3-8563-700514b38e46",
"code": "request.header.missing",
"detail": "The request is missing a required header",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#requestheadermissing"
}
]
}{
"errors": [
{
"id": "a24bc325-3929-4d9d-9c08-b3aa532685b7",
"code": "request.rate-limit",
"detail": "Too many requests",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#requestrate-limit"
}
]
}{
"errors": [
{
"id": "a24bc325-3929-4d9d-9c08-b3aa532685b7",
"code": "internal",
"detail": "An internal error occurred",
"docUrl": "https://docs.payrails.com/docs/resources/error-codes#internal"
}
]
}Authorizations
You can use an OAuth2 JWT bearer token in the Authorization header of your API requests for supported endpoints: Authorization: Bearer <YOUR_JWT_HERE>.
These tokens are valid for 10 minutes and can be requested via the access token endpoint endpoint.
Headers
Idempotency key to be used. Sending again the same key would return the same result without re-executing the update.
Content Type key to indicate the original media type of the resource.
Body
Identity provider connection type.
SAML Allowed SSO providers.
auth0, jumpcloud, keycloak, microsoft, okta Response
Created.
Identity provider connection managed by the SSO service.
Unique identifier of the SSO connection.
Identifier assigned by the downstream identity provider.
Identity provider connection type.
SAML Lifecycle status of the connection.
enabled, disabled Internal name assigned to the connection.
Display label returned to clients initiating SSO.
Allowed/Supported SSO providers.
auth0, jumpcloud, keycloak, microsoft, okta ISO-8601 timestamp when the connection was created.
ISO-8601 timestamp when the connection was last updated.