API authentication is done using OAuth 2.0 (RFC 6749), which provides a secure way for you to interact with our service without sending passwords over the network or requiring login information from your users.

If you're developing a desktop or a mobile client that will be distributed to anyone other than yourself, the steps here don't apply. Please get in touch, and we'll set up an implicit grant method for you.

Here's how API authentication works:

  1. Send your user to a special link on this site, which will let them authorize your software to access their data.

  2. We will redirect the user's browser back to your site using a URL that you specify, with an authorization code.

  3. Trade the authorization code for an access token, which you can then use to access the user's data via the API.

Step 1: User Authorizes Your Application

Start by sending your user to the following URL:

GET https://www.prayerletters.com/my/oauth/authorize

Include the following request query parameters:


As provided by us. This tells us who you are, so we can show your name to the user, and so that we know where to redirect the user.


Set this parameter to code.


Each API module has a list of permissions available. In order to make API calls that access private information, you will need to have one or more permissions from the user.

Include the permissions your application requires as a space-separated list.


If you set this parameter, we will include it when sending the user back to your application. Use it if you need some way to identify the user when they return to your site after the authorization step.

The user will be prompted to log in and then be given information about your application and the permissions you're requesting, with the option of allowing or denying the request.

If the user has previously authorized your application to access the requested scope, they will be prompted to log in (if necessary), but will then be immediately redirected back to your app without having to allow access a second time.

Once the user has either approved or denied your request, their browser will be redirected back to the callback URL that we have on file for your client. The response will contain either a code parameter (if approved) or an error parameter (if denied).

Sample Callback (Authorized)

GET https://www.your_application.com/path/to/callback?code=j7hloohprhzngv57

Sample Callback (Denied)

GET https://www.your_application.com/path/to/callback?error=access_denied

Possible Errors

For errors related to your client_id, we will display a message to the user asking them to get in contact with you.

If we can identify the client_id but the request is invalid for some reason, we will sent the user to your callback URL with error and error_description parameters to help you troubleshoot what happened.

Your code can look at the error parameter and react accordingly. It should not use the error_description except to show it to you, as we may revise it in the future without warning or notice.

Missing parameters or duplicate parameters.
You've asked for permissions that don't exist.
We only support authorization codes at this time.
Your client access is either not set up properly or has been blocked. Please contact us.
Either API access is currently unavailable for maintenance or some other reason, or else your client access is being throttled.

Step 2: Exchange the Authorization Code for a Token

Once the user has been redirect back to your site and you have an authorization code, you then need to exchange that code for a token.

POST https://www.prayerletters.com/oauth/token

Use Basic authentication to set your client_id (username) and client_secret (password), if possible.

If your HTTP library doesn't support Basic authentication, you can include client_id and client_secret as query parameters instead.

Include the following request query parameters:

Set this to authorization_code.
The authorization code received in the previous step.

Sample Response

Under normal circumstances, we will respond with a JSON object whether or not your request is successful, but you should verify this by checking the Content-Type header.

A successful response will look like this:

HTTP/1.1 200 OK
Content-Type: application/json
{ "access_token" : "gglny4db3uuzmkf09lp4uja93ekwsh1a", "token_type" : "bearer" }

An error response will look like this:

HTTP/1.1 400 Bad Request
Content-Type: application/json
{ "error" : "invalid_grant", "error_description" : "The requested authorization has expired.", }

You can now delete the authorization code and store the access token. You will use this for future API calls on behalf of the user, instead of the client credentials.

Possible Errors

400 invalid_client
You need to identify yourself, either in a Basic Authorization header, or by setting client_id and client_secret query parameters.
400 invalid_grant
The specified authorization code doesn't exist or has expired.
400 invalid_request
A required parameter was omitted or was included more than once.
400 unsupported_grant_type
You requested an unsupported grant_type.
401 invalid_client
Your client credentials were not recognized, or your access has been temporarily or permanently blocked.
408 invalid_client
429 invalid_client
Your client access is currently being throttled. (We are currently sending status 408, but will be transitioning to the more appropriate status 429.)
400 invalid_client
Your client credentials were not recognized.

Step 3: Make API Calls

Once you have an access token, you're all set to make API calls. You'll need to include the access token with every request.

We like having happy programmers, so we support both of the methods included in the specification, plus a third:

  1. The method recommended by the OAuth 2.0 standard is to use a "Bearer" Authorization header in your request, such as the following:

    Authorization: Bearer gglny4db3uuzmkf09lp4uja93ekwsh1a

    If you're using an OAuth library for your language, it will probably have built-in support for this authentication method. If you're using an HTTP library, you should be able to set the Authorization header manually.

  2. If your HTTP library doesn't let you set the Authorization header, you can also include your access token as a query parameter. This is particularly handy for testing from the command line or in a browser.

  3. For HTTP clients that support Basic authentication but don't let you set the header manually, you can enter your access token as the user name. We will ignore the password, so you can leave it blank.