# Spike Statements API

This page provides an overview of the /pdf endpoint.

This documentation forms part of the suite of technical resources which we provide in order to help developers make use of the Spike API.

# Authorization

All Spike API queries are authorized using a JWT (opens new window) bearer tokens. See the authorization guide for more info.

# Request schema

The request is simple - you need to send us the pdf (as a base64 encoded buffer) and optionally the password (if the pdf is encrypted). In addition there's a filename parameter - this is not used by the extraction process so you can send any text you like.

Here's an example:

{
  "file": "absa.pdf", // filename - can also be used by client as a request identifier
  "buffer": "JVBER...", // the base64 encoded pdf. all buffers will begin with "JVBER" because `Buffer.from("%PDF").toString('base64') === 'JVBERg=='`
  "pass": "password" // optional: required if pdf is password protected
}
1
2
3
4
5

# Response schema

There is more than one response schema. This is necessary because the data that is contained in the statements vary. We've identified a number of common patterns and created schemas to describe them:

Category Example Name Description
bank statements json normal a typical current or cheque account bank statement with date, description, amount, balance
bank statements json no balance some small number of bank statements don't have a balance
credit card statements json simple credit card formats that contain transactions only and no breakdown
credit card statements json breakdown credit card formats that include a breakdown
credit card statements json breakdown-multi-user credit card formats with breakdown for multiple linked users

# Examples

# curl

#!/bin/bash
#
# usage: spike-statements-api.sh /path/to/token /path/to/your.pdf [password]
#
set -e # Exit immediately if a command exits with a non-zero status

FULLSCRIPTPATH=$(readlink --canonicalize $0) # full path, in case ./script.sh used
BASEDIR=$(dirname $FULLSCRIPTPATH)
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
RED='\033[0;31m'
GREEN='\033[0;32m'
DARKGRAY='\033[0;90m'
NC='\033[0m' # No Color

usage() {
  echo "usage: $0 {TOKEN} {FILE} {PASS?}"
};

if [ -z "$1" ]
then
  usage
  exit -1
fi

if [ -z "$2" ]
then
  usage
  exit -1
fi

TOKENPATH=$1
FILE=$2 # e.g. e.g. ./absa.2017-01.pdf
PASS=$3

URL=https://api.spikedata.co.za/pdf
FILENAME=$(basename $FILE)
TOKEN=$(cat $TOKENPATH)

# body - see spike-api-public/client-gw/pdf.js - for the request body schema
BUFFER=`base64 -w 0 $FILE`
TEMPDIR=$(mktemp -d /tmp/XXXX)
DATAFILE=$TEMPDIR/request.json
echo "{
  \"file\": \"$FILENAME\",
  \"buffer\": \"$BUFFER\",
  \"pass\": \"$PASS\"
}" > $DATAFILE
printf "${YELLOW}"
echo "curl -X POST \"${URL}\" -H \"Content-Type: application/json\" -H \"Authorization: Bearer $TOKEN\" --data @$DATAFILE -sD -"
printf "${NC}"
curl -X POST "${URL}" -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" --data @$DATAFILE -sD -
echo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

# node.js

const StatementsApi = require("@spike/api-statements");

// TODO: inputs
const TOKEN = "...";
const FILE = "/path/to/your.pdf";
const PASS = undefined;

async function run() {
  try {
    // request
    console.log(`requesting ${StatementsApi.constants.url} ...`);
    const spikeResponse = await StatementsApi.pdf.request2(
      TOKEN,
      FILE,
      PASS
    );

    // NOTE:
    // - the .js sample does not benefit from typechecking
    // - try sample-simple-ts to get intellisense on the spikeResponse object

    // process response
    if (spikeResponse.type === StatementsApi.constants.TYPES.SUCCESS) {
      console.log("JSON", JSON.stringify(spikeResponse, null, 2));
      console.log("SUCCESS");
    } else {
      console.error(
        "ERROR:",
        StatementsApi.constants.TYPES[spikeResponse.type] +
          ":" +
          spikeResponse.code
      );
    }
  } catch (e) {
    const error = StatementsApi.response.getErrorResponseType(e);
    switch (error.type) {
      case 1:
        console.error(
          "EXCEPTION: invalid inputs:\n ",
          error.data.join("\n ")
        );
        break;
      case StatementsApi.response.ErrorResponseType.tooBig:
        console.error("EXCEPTION: the pdf is too large");
        break;
      case StatementsApi.response.ErrorResponseType.timeout:
        console.error("EXCEPTION: the request timed out");
        break;
      case StatementsApi.response.ErrorResponseType.netDown:
        console.error("EXCEPTION: the network is down");
        break;
      case StatementsApi.response.ErrorResponseType.unknownStatusCode:
        // e.g. 403=Forbidden, 404=Not Found, 405=Method Not Allowed etc...
        console.error("EXCEPTION: http error:", error.data);
        break;
      default:
        // some other network problem or perhaps and exception in your code (i.e. inside the try block above?)
        console.error("EXCEPTION: unknown exception:", e);
    }
  }
}

run();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

# Sample code

Spike provides various sample apps which you can use as demonstrations of how to use the Spike API. These can all be found in the samples repo (opens new window). See the README in that repo for a table of samples.

# Testing sandbox

You can use our test endpoint https://api.spikedata.co.za/pdf2test during development in order to prevent being charged per request. This endpoint takes exactly the same request and returns a simlar response to the latest production endpoint (https://api.spikedata.co.za/pdf2). Note: the sandbox response is limited in various ways (e.g. transactions will be truncated) to ensure that the sandbox is not used by production code.

Updated: 4/30/2024, 2:19:43 PM