Authentication

Overview

The Caxton API, is a comprehensive suite of endpoints that empowers companies to enhance their financial operations, by managing supplier payments, expenses, payroll, and other business processes through a single unified service.

Our dedicated API integration merges with your systems, enabling you to harness your data for diverse payment outputs with precision and frequency.

Request Access

To receive your API credentials, please send us a message to Request Access. Our team can then provide you with a Username and Clientname to access the Main Account.

Links

Once access has been granted by our Team, the Sandbox and Production environments, can be found via the following links.

Step 1. Generate Password

To generate a password for a Main Account:

  1. Call POST - Generate Password.
  2. Enter the Username.
  3. Enter the Clientname.
  4. If the request is submitted successfully, a ClientPassword is created.

📘

Note

If you are accessing your main account for the first time, the Username and Clientname are provided to you by our team.

REQUEST

This is what an example request looks like when you populate your Username and Clientname:

curl --request POST \
     --url https://sandbox.caxton.io/api/clients/auth/register \
     --header 'accept: application/json' \
     --header 'content-type: text/json' \
     --data '
{
  "Username": "<username>",
  "Clientname": "cxtnclient"
}

RESPONSE

The following shows a successful response, notice how the ClientPassword is generated on line four:

{
    "Content": {
        "Model": {
            "ClientPassword": "<clientpassword>",
            "StartDate": "2023-08-23T10:55:45.0645017Z",
            "EndDate": "2023-09-22T10:55:45.0645017Z",
            "PublicKey": "<publickey>",
            "ApiStatusCode": 100,
            "ApiStatus": "IsValid",
            "ApiStatusDescription": "Valid Operation"
        },
        "ExpectedResponses": [
            "IsValid"
        ]
    }
}

Step 2 - Generate Access Token

After generating a password, the next step is to generate an access_token.

Call POST - Get Access Token and populate the following:

  1. For Grant_Type. Type password.
  2. Enter the Username provided to you by our Team.
  3. Enter the ClientPassword created in Step 1 - Generate Password.
  4. If the request is submitted successfully, an access_token is created.

REQUEST

curl --request POST \
     --url https://sandbox.caxton.io/api/token \
     --header 'accept: */*' \
     --header 'content-type: application/x-www-form-urlencoded' \
     --data Grant_Type=password \
     --data Password=<password> \
     --data Username=<username>

RESPONSE

This is an example response, with the access token as shown on line two:

{
  "access_token": "<access_token>",
  "token_type": "bearer",
  "expires_in": 2591999
}

expires_in is in seconds. By default, this is 30 days.

Step 3 - User Login

To log in:

  1. Call POST - User Login.
  2. For UserName enter the email address used to register the account.
  3. Password must be hashed using md5 then converted to a hex before being packaged as base64. The following snippets are available:
using System;
using System.Security.Cryptography;
using System.Text;

public class Program
{
    public static void Main()
    {
        Console.WriteLine(PasswordHash("Admin@123"));
    }

    public static string PasswordHash(string password)
    {
        using (MD5 md5 = MD5.Create())
        {
            byte[] inputBytes = Encoding.ASCII.GetBytes(password);
            byte[] hashBytes = md5.ComputeHash(inputBytes);

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hashBytes.Length; i++)
            {
                sb.Append(hashBytes[i].ToString("X2"));
            }
            return sb.ToString();
        }
    }
}

#include <stdio.h>
#include <string.h>
#include <openssl/md5.h>

void password_hash(char *password, char *output) {
    unsigned char digest[16];
    MD5_CTX ctx;
    MD5_Init(&ctx);
    MD5_Update(&ctx, password, strlen(password));
    MD5_Final(digest, &ctx);

    for(int i = 0; i < 16; ++i)
        sprintf(&output[i*2], "%02x", (unsigned int)digest[i]);
}

int main() {
    char output[33];
    password_hash("Admin@123", output);
    printf("%s\n", output);
    return 0;
}

#include <iostream>
#include <openssl/md5.h>

std::string password_hash(std::string password) {
    unsigned char digest[MD5_DIGEST_LENGTH];
    MD5((unsigned char*)password.c_str(), password.size(), (unsigned char*)&digest);    

    char mdString[33];
    for(int i = 0; i < 16; i++)
         sprintf(&mdString[i*2], "%02x", (unsigned int)digest[i]);

    return std::string(mdString);
}

int main() {
    std::cout << password_hash("Admin@123") << std::endl;
    return 0;
}

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class Main {
    public static void main(String[] args) throws NoSuchAlgorithmException {
        System.out.println(passwordHash("Admin@123"));
    }

    public static String passwordHash(String password) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(password.getBytes());
        byte[] digest = md.digest();
        return Base64.getEncoder().encodeToString(digest);
    }
}

// Hex Encryption Algorithm
function hex2a(hexx) {
    var hex = hexx.toString(); //force conversion
    var str = '';
    for (var i = 0; i < hex.length; i += 2) {
        str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
    }
    return str;
}

// Password Hashing Algorithm
function passwordHash(password) {
    var hashed = hex2a(md5(password));
    return btoa(hashed);
}
console.log(passwordHash('Admin@123'));

<?php

// Hex Encryption Algorithm
function hex2a($hexx) {
    $hex = strval($hexx); //force conversion
    $str = '';
    for ($i = 0; $i < strlen($hex); $i += 2) {
        $str .= chr(hexdec(substr($hex, $i, 2)));
    }
    return $str;
}

// Password Hashing Alorithm
function passwordHash($password) {
	$hashed = hex2a(md5($password));
	return base64_encode($hashed);
}
echo passwordHash('Admin@123');

extern crate crypto;
extern crate base64;
use crypto::digest::Digest;
use crypto::md5::Md5;

fn password_hash(password: &str) -> String {
    let mut hasher = Md5::new();
    hasher.input_str(password);
    let hashed = hasher.result_str();
    return base64::encode(&hashed);
}

fn main() {
    println!("{}", password_hash("Admin@123"));
}

  1. For Authorization, type bearer, add a space, and enter the access token .

REQUEST

curl --location 'https://caxapi-test.azurewebsites.net/api/users/auth/login-step-one' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer <accesstoken>' \
--data-raw '{
    "username": "<username>",
    "Password": "<Password>",
    "DeviceId": "<DeviceId>",
    "Device": "<Device>"
    }
'

RESPONSE

{
    "Content": {
        "Model": {
            "LoginToken": "<LoginToken>",
            "TokenStartDate": "2024-02-09T00:00:00",
            "TokenEndDate": "2024-02-10T00:00:00",
            "Details": {
                "Id": "<Id>",
                "Title": "Ms",
                "FirstName": "User",
                "LastName": "Test",
                "Gender": "Other",
                "Address1": "The House",
                "Address2": null,
                "City": "London",
                "County": null,
                "Postcode": "N76FJ",
                "Country": "GB",
                "ContactEmail": "[email protected]",
                "PhoneNumber": "75565645644",
                "MobileNumber": "+447666778899",
                "DefaultCurrency": "EUR",
                "ReferralCode": null,
                "Email": "[email protected]",
                "MobilePhoneValidationStatus": 260
            },
            "Claims": {
                "IsCorporateDomesticAccount": false,
                "IsCorporateDomesticRestrictATMAccount": false,
                "IsCorporateAccount": true,
                "CorporateEntityId": 0000,
                "CorporateEntityName": "renameofmyco",
                "CorporateIdentityNumber": "1234567890",
                "ForcePasswordReset": false,
                "CanAccessCurrencyCards": true,
                "CanAccessMoneyTransfer": true,
                "OptedInForCommunications": false,
                "IPDataCaptureRequired": false,
                "ApiStatusCode": 100,
                "ApiStatus": "IsValid",
                "ApiStatusDescription": "Valid Operation"
            },
            "PushNotificationStatus": 0,
            "ApiStatusCode": 210,
            "ApiStatus": "LoginSuccess",
            "ApiStatusDescription": "Login successful."
        },
        "ExpectedResponses": [
            "LoginSuccess",
            "LoginTokenGenerated",
            "LoginSuccessRedAccountSignup",
            "LoginSuccessIPAccountSignup",
            "LoginSuccessEmailNotConfirmed"
        ]
    },
    "AuthorisedClientModel": {
        "ClientId": "<clientid>",
        "ClientRef": "<clientref>",
        "UserId": "<userid>",
        "TokenStartDate": "2024-01-09T09:39:00.5756167",
        "TokenEndDate": "2024-02-11T09:50:44.0200074",
        "ApiStatusCode": 100,
        "ApiStatus": "IsValid",
        "ApiStatusDescription": "Valid Operation"
    },
    "AuthorisedUserModel": {
        "UserId": "<userid>",
        "AppVersion": "20240206.2",
        "TokenStartDate": "2024-02-09T00:00:00",
        "TokenEndDate": "2024-02-10T00:00:00",
        "LoginTimestamp": "2024-02-09T09:50:43.7543498",
        "ApiLoginType": 1,
        "ApiStatusCode": 100,
        "ApiStatus": "IsValid",
        "ApiStatusDescription": "Valid Operation"
    }

Reset Password

To reset the password for the Main Account follow these instructions:

  1. Call PUT - Reset Client Credentials to reset the client password. If the password is being reset for a Sub-Account, proceed to the next step, otherwise, skip to Step 3.
  2. Enter the IdentityNumber for the Sub-Account.
  3. Follow Step 1. Generate Password.
  4. Follow Step 2. Generate Access Token