Connect your app to Goodreads

To configure a Goodreads connection with Auth0, you will need to register your app on the Goodreads developers site.

This doc refers to the client steps to connect your client. If you are looking to manage authentication in your application, see Next Steps below.

1. Apply for a developer key

Log into the Goodreads developer site, and select developer key:

2. Enter information about your app

Complete the form then click Apply for a Developer Key. Enter this in the Callback URL field:

https://YOUR_AUTH0_DOMAIN/login/callback

3. Get your Consumer Key and Consumer Secret

Once the application is registered, the Key and Secret for your new app will be displayed on the following page:

4. Create the Goodreads connection

You will need to use this endpoint of our Management API v2 to create a custom oauth1 connection for Goodreads.

Read our documentation on creating generic OAuth1 connections for more information on the individual fields used in the sample payload to follow. For Goodreads, this is a sample payload to create the connection:


curl --request POST \
  --url 'https://YOUR_AUTH0_DOMAIN/api/v2/connections' \
  --header 'authorization: Bearer YOUR_API_V2_TOKEN_HERE' \
  --data '{"name": "custom-goodreads","strategy": "oauth1","enabled_clients": ["YOUR_ENABLED_CLIENT_ID"],"options": {"client_id": "YOUR_GOODREADS_KEY","client_secret": "YOUR_GOODREADS_SECRET","requestTokenURL": "http://www.goodreads.com/oauth/request_token","accessTokenURL": "http://www.goodreads.com/oauth/access_token","userAuthorizationURL": "http://www.goodreads.com/oauth/authorize","scripts": {"fetchUserProfile": "function(token, tokenSecret, ctx, cb) {var OAuth = new require(\"oauth\").OAuth; var parser = require('\''xml2json'\''); var oauth = new OAuth(ctx.requestTokenURL, ctx.accessTokenURL, ctx.client_id, ctx.client_secret, \"1.0\", null, \"HMAC-SHA1\"); oauth.get(\"https://www.goodreads.com/api/auth_user\", token, tokenSecret, function(e, xml, r) { console.log(xml); if (e) return cb(e); if (r.statusCode !== 200) return cb(new Error(\"StatusCode: \" + r.statusCode)); try { var jsonResp = JSON.parse(parser.toJson(xml)); var user = jsonResp.GoodreadsResponse.user; cb(null, user); } catch (e) { console.log(e); cb(new UnauthorizedError(\"[+] fetchUserProfile: Goodreads fetch script failed. Check Webtask logs\")); } });}"}}}'
var client = new RestClient("https://YOUR_AUTH0_DOMAIN/api/v2/connections");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer YOUR_API_V2_TOKEN_HERE");
request.AddParameter("undefined", "{\"name\": \"custom-goodreads\",\"strategy\": \"oauth1\",\"enabled_clients\": [\"YOUR_ENABLED_CLIENT_ID\"],\"options\": {\"client_id\": \"YOUR_GOODREADS_KEY\",\"client_secret\": \"YOUR_GOODREADS_SECRET\",\"requestTokenURL\": \"http://www.goodreads.com/oauth/request_token\",\"accessTokenURL\": \"http://www.goodreads.com/oauth/access_token\",\"userAuthorizationURL\": \"http://www.goodreads.com/oauth/authorize\",\"scripts\": {\"fetchUserProfile\": \"function(token, tokenSecret, ctx, cb) {var OAuth = new require(\\\"oauth\\\").OAuth; var parser = require('xml2json'); var oauth = new OAuth(ctx.requestTokenURL, ctx.accessTokenURL, ctx.client_id, ctx.client_secret, \\\"1.0\\\", null, \\\"HMAC-SHA1\\\"); oauth.get(\\\"https://www.goodreads.com/api/auth_user\\\", token, tokenSecret, function(e, xml, r) { console.log(xml); if (e) return cb(e); if (r.statusCode !== 200) return cb(new Error(\\\"StatusCode: \\\" + r.statusCode)); try { var jsonResp = JSON.parse(parser.toJson(xml)); var user = jsonResp.GoodreadsResponse.user; cb(null, user); } catch (e) { console.log(e); cb(new UnauthorizedError(\\\"[+] fetchUserProfile: Goodreads fetch script failed. Check Webtask logs\\\")); } });}\"}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

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

func main() {

	url := "https://YOUR_AUTH0_DOMAIN/api/v2/connections"

	payload := strings.NewReader("{\"name\": \"custom-goodreads\",\"strategy\": \"oauth1\",\"enabled_clients\": [\"YOUR_ENABLED_CLIENT_ID\"],\"options\": {\"client_id\": \"YOUR_GOODREADS_KEY\",\"client_secret\": \"YOUR_GOODREADS_SECRET\",\"requestTokenURL\": \"http://www.goodreads.com/oauth/request_token\",\"accessTokenURL\": \"http://www.goodreads.com/oauth/access_token\",\"userAuthorizationURL\": \"http://www.goodreads.com/oauth/authorize\",\"scripts\": {\"fetchUserProfile\": \"function(token, tokenSecret, ctx, cb) {var OAuth = new require(\\\"oauth\\\").OAuth; var parser = require('xml2json'); var oauth = new OAuth(ctx.requestTokenURL, ctx.accessTokenURL, ctx.client_id, ctx.client_secret, \\\"1.0\\\", null, \\\"HMAC-SHA1\\\"); oauth.get(\\\"https://www.goodreads.com/api/auth_user\\\", token, tokenSecret, function(e, xml, r) { console.log(xml); if (e) return cb(e); if (r.statusCode !== 200) return cb(new Error(\\\"StatusCode: \\\" + r.statusCode)); try { var jsonResp = JSON.parse(parser.toJson(xml)); var user = jsonResp.GoodreadsResponse.user; cb(null, user); } catch (e) { console.log(e); cb(new UnauthorizedError(\\\"[+] fetchUserProfile: Goodreads fetch script failed. Check Webtask logs\\\")); } });}\"}}}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("authorization", "Bearer YOUR_API_V2_TOKEN_HERE")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://YOUR_AUTH0_DOMAIN/api/v2/connections")
  .header("authorization", "Bearer YOUR_API_V2_TOKEN_HERE")
  .body("{\"name\": \"custom-goodreads\",\"strategy\": \"oauth1\",\"enabled_clients\": [\"YOUR_ENABLED_CLIENT_ID\"],\"options\": {\"client_id\": \"YOUR_GOODREADS_KEY\",\"client_secret\": \"YOUR_GOODREADS_SECRET\",\"requestTokenURL\": \"http://www.goodreads.com/oauth/request_token\",\"accessTokenURL\": \"http://www.goodreads.com/oauth/access_token\",\"userAuthorizationURL\": \"http://www.goodreads.com/oauth/authorize\",\"scripts\": {\"fetchUserProfile\": \"function(token, tokenSecret, ctx, cb) {var OAuth = new require(\\\"oauth\\\").OAuth; var parser = require('xml2json'); var oauth = new OAuth(ctx.requestTokenURL, ctx.accessTokenURL, ctx.client_id, ctx.client_secret, \\\"1.0\\\", null, \\\"HMAC-SHA1\\\"); oauth.get(\\\"https://www.goodreads.com/api/auth_user\\\", token, tokenSecret, function(e, xml, r) { console.log(xml); if (e) return cb(e); if (r.statusCode !== 200) return cb(new Error(\\\"StatusCode: \\\" + r.statusCode)); try { var jsonResp = JSON.parse(parser.toJson(xml)); var user = jsonResp.GoodreadsResponse.user; cb(null, user); } catch (e) { console.log(e); cb(new UnauthorizedError(\\\"[+] fetchUserProfile: Goodreads fetch script failed. Check Webtask logs\\\")); } });}\"}}}")
  .asString();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://YOUR_AUTH0_DOMAIN/api/v2/connections",
  "method": "POST",
  "headers": {
    "authorization": "Bearer YOUR_API_V2_TOKEN_HERE"
  },
  "processData": false,
  "data": "{\"name\": \"custom-goodreads\",\"strategy\": \"oauth1\",\"enabled_clients\": [\"YOUR_ENABLED_CLIENT_ID\"],\"options\": {\"client_id\": \"YOUR_GOODREADS_KEY\",\"client_secret\": \"YOUR_GOODREADS_SECRET\",\"requestTokenURL\": \"http://www.goodreads.com/oauth/request_token\",\"accessTokenURL\": \"http://www.goodreads.com/oauth/access_token\",\"userAuthorizationURL\": \"http://www.goodreads.com/oauth/authorize\",\"scripts\": {\"fetchUserProfile\": \"function(token, tokenSecret, ctx, cb) {var OAuth = new require(\\\"oauth\\\").OAuth; var parser = require('xml2json'); var oauth = new OAuth(ctx.requestTokenURL, ctx.accessTokenURL, ctx.client_id, ctx.client_secret, \\\"1.0\\\", null, \\\"HMAC-SHA1\\\"); oauth.get(\\\"https://www.goodreads.com/api/auth_user\\\", token, tokenSecret, function(e, xml, r) { console.log(xml); if (e) return cb(e); if (r.statusCode !== 200) return cb(new Error(\\\"StatusCode: \\\" + r.statusCode)); try { var jsonResp = JSON.parse(parser.toJson(xml)); var user = jsonResp.GoodreadsResponse.user; cb(null, user); } catch (e) { console.log(e); cb(new UnauthorizedError(\\\"[+] fetchUserProfile: Goodreads fetch script failed. Check Webtask logs\\\")); } });}\"}}}"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://YOUR_AUTH0_DOMAIN/api/v2/connections',
  headers: { authorization: 'Bearer YOUR_API_V2_TOKEN_HERE' },
  body: 
   { name: 'custom-goodreads',
     strategy: 'oauth1',
     enabled_clients: [ 'YOUR_ENABLED_CLIENT_ID' ],
     options: 
      { client_id: 'YOUR_GOODREADS_KEY',
        client_secret: 'YOUR_GOODREADS_SECRET',
        requestTokenURL: 'http://www.goodreads.com/oauth/request_token',
        accessTokenURL: 'http://www.goodreads.com/oauth/access_token',
        userAuthorizationURL: 'http://www.goodreads.com/oauth/authorize',
        scripts: { fetchUserProfile: 'function(token, tokenSecret, ctx, cb) {var OAuth = new require("oauth").OAuth; var parser = require(\'xml2json\'); var oauth = new OAuth(ctx.requestTokenURL, ctx.accessTokenURL, ctx.client_id, ctx.client_secret, "1.0", null, "HMAC-SHA1"); oauth.get("https://www.goodreads.com/api/auth_user", token, tokenSecret, function(e, xml, r) { console.log(xml); if (e) return cb(e); if (r.statusCode !== 200) return cb(new Error("StatusCode: " + r.statusCode)); try { var jsonResp = JSON.parse(parser.toJson(xml)); var user = jsonResp.GoodreadsResponse.user; cb(null, user); } catch (e) { console.log(e); cb(new UnauthorizedError("[+] fetchUserProfile: Goodreads fetch script failed. Check Webtask logs")); } });}' } } },
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"authorization": @"Bearer YOUR_API_V2_TOKEN_HERE" };
NSDictionary *parameters = @{ @"name": @"custom-goodreads",
                              @"strategy": @"oauth1",
                              @"enabled_clients": @[ @"YOUR_ENABLED_CLIENT_ID" ],
                              @"options": @{ @"client_id": @"YOUR_GOODREADS_KEY", @"client_secret": @"YOUR_GOODREADS_SECRET", @"requestTokenURL": @"http://www.goodreads.com/oauth/request_token", @"accessTokenURL": @"http://www.goodreads.com/oauth/access_token", @"userAuthorizationURL": @"http://www.goodreads.com/oauth/authorize", @"scripts": @{ @"fetchUserProfile": @"function(token, tokenSecret, ctx, cb) {var OAuth = new require(\"oauth\").OAuth; var parser = require('xml2json'); var oauth = new OAuth(ctx.requestTokenURL, ctx.accessTokenURL, ctx.client_id, ctx.client_secret, \"1.0\", null, \"HMAC-SHA1\"); oauth.get(\"https://www.goodreads.com/api/auth_user\", token, tokenSecret, function(e, xml, r) { console.log(xml); if (e) return cb(e); if (r.statusCode !== 200) return cb(new Error(\"StatusCode: \" + r.statusCode)); try { var jsonResp = JSON.parse(parser.toJson(xml)); var user = jsonResp.GoodreadsResponse.user; cb(null, user); } catch (e) { console.log(e); cb(new UnauthorizedError(\"[+] fetchUserProfile: Goodreads fetch script failed. Check Webtask logs\")); } });}" } } };

NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_AUTH0_DOMAIN/api/v2/connections"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                if (error) {
                                                    NSLog(@"%@", error);
                                                } else {
                                                    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                    NSLog(@"%@", httpResponse);
                                                }
                                            }];
[dataTask resume];
$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://YOUR_AUTH0_DOMAIN/api/v2/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 => "{\"name\": \"custom-goodreads\",\"strategy\": \"oauth1\",\"enabled_clients\": [\"YOUR_ENABLED_CLIENT_ID\"],\"options\": {\"client_id\": \"YOUR_GOODREADS_KEY\",\"client_secret\": \"YOUR_GOODREADS_SECRET\",\"requestTokenURL\": \"http://www.goodreads.com/oauth/request_token\",\"accessTokenURL\": \"http://www.goodreads.com/oauth/access_token\",\"userAuthorizationURL\": \"http://www.goodreads.com/oauth/authorize\",\"scripts\": {\"fetchUserProfile\": \"function(token, tokenSecret, ctx, cb) {var OAuth = new require(\\\"oauth\\\").OAuth; var parser = require('xml2json'); var oauth = new OAuth(ctx.requestTokenURL, ctx.accessTokenURL, ctx.client_id, ctx.client_secret, \\\"1.0\\\", null, \\\"HMAC-SHA1\\\"); oauth.get(\\\"https://www.goodreads.com/api/auth_user\\\", token, tokenSecret, function(e, xml, r) { console.log(xml); if (e) return cb(e); if (r.statusCode !== 200) return cb(new Error(\\\"StatusCode: \\\" + r.statusCode)); try { var jsonResp = JSON.parse(parser.toJson(xml)); var user = jsonResp.GoodreadsResponse.user; cb(null, user); } catch (e) { console.log(e); cb(new UnauthorizedError(\\\"[+] fetchUserProfile: Goodreads fetch script failed. Check Webtask logs\\\")); } });}\"}}}",
  CURLOPT_HTTPHEADER => array(
    "authorization: Bearer YOUR_API_V2_TOKEN_HERE"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("")

payload = "{\"name\": \"custom-goodreads\",\"strategy\": \"oauth1\",\"enabled_clients\": [\"YOUR_ENABLED_CLIENT_ID\"],\"options\": {\"client_id\": \"YOUR_GOODREADS_KEY\",\"client_secret\": \"YOUR_GOODREADS_SECRET\",\"requestTokenURL\": \"http://www.goodreads.com/oauth/request_token\",\"accessTokenURL\": \"http://www.goodreads.com/oauth/access_token\",\"userAuthorizationURL\": \"http://www.goodreads.com/oauth/authorize\",\"scripts\": {\"fetchUserProfile\": \"function(token, tokenSecret, ctx, cb) {var OAuth = new require(\\\"oauth\\\").OAuth; var parser = require('xml2json'); var oauth = new OAuth(ctx.requestTokenURL, ctx.accessTokenURL, ctx.client_id, ctx.client_secret, \\\"1.0\\\", null, \\\"HMAC-SHA1\\\"); oauth.get(\\\"https://www.goodreads.com/api/auth_user\\\", token, tokenSecret, function(e, xml, r) { console.log(xml); if (e) return cb(e); if (r.statusCode !== 200) return cb(new Error(\\\"StatusCode: \\\" + r.statusCode)); try { var jsonResp = JSON.parse(parser.toJson(xml)); var user = jsonResp.GoodreadsResponse.user; cb(null, user); } catch (e) { console.log(e); cb(new UnauthorizedError(\\\"[+] fetchUserProfile: Goodreads fetch script failed. Check Webtask logs\\\")); } });}\"}}}"

headers = { 'authorization': "Bearer YOUR_API_V2_TOKEN_HERE" }

conn.request("POST", "/YOUR_AUTH0_DOMAIN/api/v2/connections", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'

url = URI("https://YOUR_AUTH0_DOMAIN/api/v2/connections")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["authorization"] = 'Bearer YOUR_API_V2_TOKEN_HERE'
request.body = "{\"name\": \"custom-goodreads\",\"strategy\": \"oauth1\",\"enabled_clients\": [\"YOUR_ENABLED_CLIENT_ID\"],\"options\": {\"client_id\": \"YOUR_GOODREADS_KEY\",\"client_secret\": \"YOUR_GOODREADS_SECRET\",\"requestTokenURL\": \"http://www.goodreads.com/oauth/request_token\",\"accessTokenURL\": \"http://www.goodreads.com/oauth/access_token\",\"userAuthorizationURL\": \"http://www.goodreads.com/oauth/authorize\",\"scripts\": {\"fetchUserProfile\": \"function(token, tokenSecret, ctx, cb) {var OAuth = new require(\\\"oauth\\\").OAuth; var parser = require('xml2json'); var oauth = new OAuth(ctx.requestTokenURL, ctx.accessTokenURL, ctx.client_id, ctx.client_secret, \\\"1.0\\\", null, \\\"HMAC-SHA1\\\"); oauth.get(\\\"https://www.goodreads.com/api/auth_user\\\", token, tokenSecret, function(e, xml, r) { console.log(xml); if (e) return cb(e); if (r.statusCode !== 200) return cb(new Error(\\\"StatusCode: \\\" + r.statusCode)); try { var jsonResp = JSON.parse(parser.toJson(xml)); var user = jsonResp.GoodreadsResponse.user; cb(null, user); } catch (e) { console.log(e); cb(new UnauthorizedError(\\\"[+] fetchUserProfile: Goodreads fetch script failed. Check Webtask logs\\\")); } });}\"}}}"

response = http.request(request)
puts response.read_body
import Foundation

let headers = ["authorization": "Bearer YOUR_API_V2_TOKEN_HERE"]
let parameters = [
  "name": "custom-goodreads",
  "strategy": "oauth1",
  "enabled_clients": ["YOUR_ENABLED_CLIENT_ID"],
  "options": [
    "client_id": "YOUR_GOODREADS_KEY",
    "client_secret": "YOUR_GOODREADS_SECRET",
    "requestTokenURL": "http://www.goodreads.com/oauth/request_token",
    "accessTokenURL": "http://www.goodreads.com/oauth/access_token",
    "userAuthorizationURL": "http://www.goodreads.com/oauth/authorize",
    "scripts": ["fetchUserProfile": "function(token, tokenSecret, ctx, cb) {var OAuth = new require(\"oauth\").OAuth; var parser = require('xml2json'); var oauth = new OAuth(ctx.requestTokenURL, ctx.accessTokenURL, ctx.client_id, ctx.client_secret, \"1.0\", null, \"HMAC-SHA1\"); oauth.get(\"https://www.goodreads.com/api/auth_user\", token, tokenSecret, function(e, xml, r) { console.log(xml); if (e) return cb(e); if (r.statusCode !== 200) return cb(new Error(\"StatusCode: \" + r.statusCode)); try { var jsonResp = JSON.parse(parser.toJson(xml)); var user = jsonResp.GoodreadsResponse.user; cb(null, user); } catch (e) { console.log(e); cb(new UnauthorizedError(\"[+] fetchUserProfile: Goodreads fetch script failed. Check Webtask logs\")); } });}"]
  ]
]

let postData = NSJSONSerialization.dataWithJSONObject(parameters, options: nil, error: nil)

var request = NSMutableURLRequest(URL: NSURL(string: "https://YOUR_AUTH0_DOMAIN/api/v2/connections")!,
                                        cachePolicy: .UseProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.HTTPMethod = "POST"
request.allHTTPHeaderFields = headers
request.HTTPBody = postData

let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    println(error)
  } else {
    let httpResponse = response as? NSHTTPURLResponse
    println(httpResponse)
  }
})

dataTask.resume()

NOTE: You have to replace YOUR_API_V2_TOKEN_HERE with a Management API v2 token. You can get one from the dashboard or follow this process if this is the first time.

This sample uses the following fetchUserProfile script, you can change it as you please:

function(token, tokenSecret, ctx, cb) {
    var OAuth = new require("oauth").OAuth;
    var parser = require('xml2json');
    var oauth = new OAuth(ctx.requestTokenURL, ctx.accessTokenURL, ctx.client_id, ctx.client_secret, "1.0", null, "HMAC-SHA1");
    oauth.get("https://www.goodreads.com/api/auth_user", token, tokenSecret, function(e, xml, r) {
        console.log(xml);
        if (e) return cb(e);
        if (r.statusCode !== 200) return cb(new Error("StatusCode: " + r.statusCode));
        try {
            var jsonResp = JSON.parse(parser.toJson(xml));
            var user = jsonResp.GoodreadsResponse.user;
            cb(null, user);
        }
        catch (e) {
            console.log(e);
            cb(new UnauthorizedError("[+] fetchUserProfile: Goodreads fetch script failed. Check Webtask logs"));
        }
    });
}

Goodreads returns limited user profile data

If you have any Rules configured that rely on user.email for example, user authentication will likely fail - the sample Rule above currently only returns user.id, user.name, and user.link properties from Goodreads' API. Please add appropriate error handling to any Rules or Hooks that may rely on other user-profile data that may be missing. You may use our Real-time Webtask Logs extension to help debug these sorts of issues further.

If you do change the fetchUserProfile script, you can stringify the function easily for use in your POST /api/v2/connections payload as follows:

JSON.stringify(`function(token, tokenSecret, ctx, cb) {
    // fetch user profile
}`);

5. Test the connection

You can use the /authorize endpoint with custom client_id and connection parameters to test your connection. For example:

https://YOUR_AUTH0_DOMAIN/authorize?
  scope=YOUR_SCOPE&
  response_type=YOUR_RESPONSE_TYPE&
  client_id=YOUR_ENABLED_CLIENT_ID&
  redirect_uri=https://YOUR_APP/callback&
  connection=custom-goodreads&
  nonce=YOUR_CRYPTOGRAPHIC_NONCE

Next Steps

Now that you have a working connection, the next step is to configure your application to use it. You can initiate login using Lock, Auth0.js, or the Authentication API endpoint.

For detailed instructions and samples for a variety of technologies, refer to our quickstarts:

For more background information on client authentication refer to Client Authentication.