{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"bb8af6b4-12d6-4d26-8500-86c8d4517c61","name":"SongSelect Partner API","description":"> **NOTICE**: CCLI has retired the SongSelect API Partner Program and is no longer accepting new API partners. \n  \n\nWelcome to the CCLI SongSelect Partner API!\n\nThis documentation can be used to become familiar with what is available in the API. Once you begin using the API, you can then use the reference below for implementation details.\n\n# Overview\n\n- Most requests require [authentication](#authentication-authorization) which is implemented with OpenID Connect / OAuth 2.0\n    \n- All API requests require a valid [subscription key](#subscription-keys) in the request header\n    \n- You will be supplied with a [development client](#development-client) to be able to test the API functionality\n    \n- The API has [rate limits](#rate-limits) to protect against malicious activity\n    \n\n# Authentication / Authorization\n\n- The API utilizes [OpenID Connect](https://openid.net/connect/) and [OAuth 2.0](https://oauth.net/2/) for authentication / authorization\n    \n- The supported flow is Authorization Code with PKCE\n    \n- The use of [refresh tokens](https://oauth.net/2/refresh-tokens/) is supported\n    \n- Settings\n    \n- Authorization endpoint: [<b>https://identityservices.ccli.com/connect/authorize</b>](https://identityservices.ccli.com/connect/authorize)\n    \n- Token endpoint: [<b>https://identityservices.ccli.com/connect/token</b>](https://identityservices.ccli.com/connect/token)\n    \n- Scope: **openid cclipartnerapi.read offline_access**\n    \n\n### Example authorization calls\n\n- The Postman redirect URI is used as an example, you would replace this with your redirect URI\n    \n- All URIs and scope must be encoded\n    \n- Line breaks added and encoding removed for readability\n    \n\n```\nGET https://identityservices.ccli.com/connect/authorize?\nresponse_type=code&\nclient_id=YOUR-CLIENTID&\nscope=openid cclipartnerapi.read offline_access&\nredirect_uri=https://www.yoursite.com/oauth/callback&\ncode_challenge=YOUR-GENERATED-CODE-CHALLENGE&\ncode_challenge_method=S256\n\n ```\n\n- The actual request would look like this\n    \n\n```\nGET https://identityservices.ccli.com/connect/authorize?response_type=code&client_id=YOUR-CLIENTID&scope=openid cclipartnerapi.read offline_access&redirect_uri=https://www.yoursite.com/oauth/callback&code_challenge=YOUR-GENERATED-CODE-CHALLENGE&code_challenge_method=S256\n\n ```\n\n### Helpful links for implementing OpenID Connect / OAuth 2.0\n\n- [What the Heck is OAuth? | Okta Developer](https://developer.okta.com/blog/2017/06/21/what-the-heck-is-oauth)\n    \n- [Implement the OAuth 2.0 Authorization Code with PKCE Flow | Okta Developer](https://developer.okta.com/blog/2019/08/22/okta-authjs-pkce)\n    \n\n# Subscription Keys\n\nYou will receive two subscription keys. First you will receive a Development Subscription Key. This is to be used for testing in Postman, as well as when you are testing your own application.\n\nWhen you are ready to move into a production phase, you will receive a Production Subscription Key that is to be used in your production application.\n\nA Subscription Key is required to be sent as part of every request to the SongSelect Partner API, in the form of an `Ocp-Apim-Subscription-Key` request header.\n\n### Subscription Key related error response\n\nIf a Subscription Key is missing, malformed, or invalid, you will receive a `401 Unauthorised` response code and the following JSON response:\n\n```\n{\n  \"statusCode\": 401,\n  \"message\": \"Access denied due to invalid subscription key. Make sure to provide a valid key for an active subscription.\"\n}\n\n ```\n\n# Development Client\n\nWith a Development client, you will be able to run this collection, and exercise the API endpoints. To do so, you will be given a Development ClientId and ClientSecret. You will then need to enter these into the CCLI Partner environment within Postman. You will also use this client to test your own application.\n\nNote that this Development client has [development restrictions](#development-restrictions) in place.\n\n# Getting Started With Postman\n\nIn order to exercise the API and actually run the endpoints listed in the Postman documentation, you  \nwill need to import the Postman collection, and enter your subscription and client information.\n\n### Get a copy of the Postman collection\n\n- In the upper right corner of this documentation, click the Run in Postman button\n    \n\n<img src=\"https://s3.us-west-2.amazonaws.com/songselect.ccli.com/PostmanDocumentation/RunInPostman.png\">\n\n- Choose to either run in Postman for Web, or Postman for Windows if you have the app installed\n    \n- Select your local workspace where you want to import the collection\n    \n- The imported Postman collection includes an environment called CCLI Partner\n    \n- In the left navigation bar, select Environments, then select the CCLI Partner environment\n    \n\n<img src=\"https://s3.us-west-2.amazonaws.com/songselect.ccli.com/PostmanDocumentation/SelectCcliPartnerEnvironment.png\">\n\n- In the environment variables to the right, enter the values you were given into the Current Value column for **ApimSubscriptionKey**, **ClientId**, and **ClientSecret**\n    \n\n<img src=\"https://s3.us-west-2.amazonaws.com/songselect.ccli.com/PostmanDocumentation/EnterEnvironmentVariables.png\">\n\n- Save the environment changes\n    \n\n### Set up the Refresh Token\n\nThe Postman collection for our API is a bit more involved than a standard collection. This is because it is set up to use refresh tokens, which allows you to have working code that demonstrates the use of refresh tokens. In order for this to work, you will need to obtain a valid refresh token and save it in a Postman variable.\n\n- In the upper right corner of Postman, select the CCLI Partner environment\n    \n\n<img src=\"https://s3.us-west-2.amazonaws.com/songselect.ccli.com/PostmanDocumentation/SelectEnvironmentpng.png\">\n\n- In the left navigation bar, select Collections\n    \n- Select the SongSelect Partner API collection name\n    \n- Select the Authorization tab\n    \n- At the bottom, click Get New Access Token\n    \n- Sign in with your CCLI credentials\n    \n- If your account is linked to multiple organizations, choose the \"SongSelect API \\[country code\\] Partners\" organization\n    \n- Click Proceed\n    \n- In the Manage Access Tokens window, scroll to the bottom and highlight the refresh_token. Then right-click and Set the Partner RefreshToken variable.\n    \n\n<img src=\"https://s3.us-west-2.amazonaws.com/songselect.ccli.com/PostmanDocumentation/SetRefreshVariable.png\">\n\n- Close the Manage Access Tokens window, you do not need to click Use Token\n    \n- Go to any of the endpoints and Send the request\n    \n\n# Development Restrictions\n\nWhen in development mode, the following restrictions are in place\n\n- Content will only be available to a user linked to a test organization such as \"SongSelect API US Partners\"\n    \n\n# Tokens\n\n### Access Token\n\n- 1 hour token Lifetime\n    \n- Refresh token may be used to get a new Access Token without user involvement\n    \n\n### Refresh Token\n\n- 60 day sliding token lifetime\n    \n- One time use, a new refresh token is included in the response\n    \n\n# Rate Limits\n\nAPI access rate limits are applied on a per user basis. There is both a short term and long term rate limit.\n\n- Short term limit: 100 calls per 10 seconds\n    \n- Long term limit: 300 calls per 5 minutes\n    \n\nIf these limits are exceeded, you will receive a `429 Too Many Requests` status code and a JSON response similar to this:\n\n```\n{\n  \"statusCode\": 429,\n  \"message\": \"Rate limit is exceeded. Try again in 7 seconds.\"\n}\n\n ```\n\n# API Reference","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"604633","team":623652,"collectionId":"bb8af6b4-12d6-4d26-8500-86c8d4517c61","publishedId":"TzseGkmA","public":true,"publicUrl":"https://documenter-api.postman.tech/view/604633/TzseGkmA","privateUrl":"https://go.postman.co/documentation/604633-bb8af6b4-12d6-4d26-8500-86c8d4517c61","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"EF5B25"},"documentationLayout":"classic-double-column","customisation":null,"version":"8.10.1","publishDate":"2022-01-12T18:22:41.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{},"logos":{}},"statusCode":200},"environments":[{"name":"CCLI Partner","id":"b0e196c4-2e4a-47a2-a87b-110c5d04008c","owner":"604633","values":[{"key":"SsApiBaseUrl","value":"https://api.ccli.com/ss","enabled":true,"type":"default"},{"key":"ApiBaseUrl","value":"https://api.ccli.com/ip","enabled":true},{"key":"PartnerApi-RootUrl","value":"https://api.ccli.com/ip/v1","enabled":true},{"key":"ccli.identityservices-base-url","value":"https://identityservices.ccli.com","enabled":true},{"key":"TokenName","value":"Identity-Partner-Prod","enabled":true},{"key":"AccessToken","value":"Your-Access-Token-Here","enabled":true},{"key":"AccessTokenExpiry","value":"","enabled":true},{"key":"RefreshToken","value":"","enabled":true},{"key":"TestSongId","value":"22025","enabled":true},{"key":"ApimSubscriptionKey","value":"Your-Subscription-Key-Here","enabled":true},{"key":"ClientId","value":"Your-Postman-ClientId-Here","enabled":true},{"key":"ClientSecret","value":"Your-Postman-Client-Secret-Here","enabled":true},{"key":"RptApiBaseUrl","value":"https://api.ccli.com/rpt","enabled":true,"type":"default"}],"published":true}],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/54475283e51160a834532dddf1349a006273c85841c759ec1325644efc688a14","favicon":""},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"},{"label":"CCLI Partner","value":"604633-b0e196c4-2e4a-47a2-a87b-110c5d04008c"}],"canonicalUrl":"https://documenter.gw.postman.com/view/metadata/TzseGkmA"}