NAV
shell

Gini Pay API Documentation v1.0

Introduction

Gini provides a system to extract the payment informations from documents like invoices, reminders and remittance slips. This API is part of the Gini Pay product. The system is capable of handling photos made with Android or iOS based devices as well as PDF files uploaded from a web application.

The API supports PDF, GIF, JPEG, PNG, and TIFF documents.

The information extraction starts when the document is sent to the extraction system. There it first gets verified and then classified as being native or scanned.

There is a difference between native and scanned PDF files. Native PDFs are created using Microsoft Word, Excel, Illustrator or other software that generates PDF files from source code. Scanned PDFs are created by scanning devices from the actual paper documents.

The native PDF documents already contain this information in the document source code and are processed accordingly. However, the scanned documents do not have the source code and therefore do not directly provide the information that can be easily read and understood by the system. Therefore, the extraction system has to apply Optical Character Recognition (OCR) and various computer vision techniques to obtain the document contents.

Once the layout and the textual contents become available for the uploaded document, the system starts extracting document semantic information such as the document sender (name, address) and meta information such as the document type (invoice, contract).

It might be so that the system is unable to extract the information correctly. This could most likely happen due to OCR errors caused by poor quality of the scanned document, incomplete textual data or quite specific document design format. In such cases it is still possible to correct the extractions by manually selecting the correct amount to pay on the document and submitting it back to the API. The extraction system will receive the feedback and help us to improve its self-learning algorithms over time.

If you have any questions about the Gini Pay API and the functionality it provides, please contact us via api@gini.net.

Important notes for migrating from api.gini.net

The most important changes when migrating from the legacy api.gini.net are:

Getting started

Welcome! In order to process your first document with the Gini Pay API, you will have to perform the following easy steps:

  1. register your application
  2. obtain an access token
  3. upload a document
  4. check the document status information
  5. retrieve the extractions
  6. send feedback

For general information about the Gini Pay API, see overview.

Register Your Application

Before you can use the Gini Pay API in your application, you need a valid client ID and a client secret. If you don't have the client ID and the client secret already, please contact your sales representative.

Obtain an Access Token

obtain an access token from an untrusted device (eg. smartphone)

curl -v -X POST --data-urlencode 'username=random@example.org'
        --data-urlencode 'password=geheim'
        -H 'Content-Type: application/x-www-form-urlencoded'
        -H 'Accept: application/json'
        -u 'client-id:client-secret'
        'https://user.gini.net/oauth/token?grant_type=password'

the JSON response will look similar to

{
  "access_token":"6c470ffa-abf1-41aa-b866-cd3be0ee84f4",
  "token_type":"bearer",
  "expires_in":3599
}

obtain an access token from a trusted device (eg. backend / gateway)

The access token is only needed if you want to create a token from a trusted device (backend) and use it from a untrusted device (smartphone). The anonymous user is created automatically for each user identified by the X-User-Identifier header.

curl -v -X POST -H 'X-User-Identifier: user1'
    -H 'Accept: application/vnd.gini.v1+json'
    -u 'client-id:secret' 'https://pay-api.gini.net/login'
POST https://pay-api.gini.net/login
Authorization: Basic Y2xpZW50LWlkOnNlY3JldA==
Host: pay-api.gini.net
Accept: application/vnd.gini.v1+json

example response

{
  "access_token":"6c470ffa-abf1-41aa-b866-cd3be0ee84f4",
  "token_type":"bearer",
  "expires_in":3599
}

6c470ffa-abf1-41aa-b866-cd3be0ee84f4 is the access token which can be used for API requests. All requests to the Gini Pay API are made on behalf of the user authorized by the access token. For now, let's assume that you've already created an anonymous user. If not, for the details on how to do so please read Direct Communication from Client Devices to the Gini Pay API

In order to get an access token for the Gini account, run the example command on the right (don't forget to replace random@example.org with your username and geheim with your password as well as client-id with your client ID and client-secret with your client secret).

Upload a Document

upload a document

curl -v -X POST --data-binary '@/path/to/your/document.pdf'
     -H 'Accept: application/vnd.gini.v1+json'
     -H 'Content-Type: application/pdf'
     -H 'Authorization: BEARER b6c470ffa-abf1-41aa-b866-cd3be0ee84f'
     'https://pay-api.gini.net/documents'

Now that you have the access token, you can upload your first document by sending an API request. The request must contain the correspoinding Gini API version number. For example for our first document, we will use Gini Pay API version v1. The command on the right will send a request against the corresponding version of the API.

the response (in case the document was Accepted)

HTTP/1.1 201 Created
X-Request-Id: 7b5a7f79-ae7c-4040-b6cf-25cde58ad937
Location: https://pay-api.gini.net/documents/b4bd3e80-7bd1-11e4-95ab-000000000000
Content-Type: application/vnd.gini.v1+json

If the file was accepted by the Gini Pay API (i.e. its file format is supported), the extraction system automatically starts to process the document and responses with the HTTP status code 201 as well as the document location URL.

Check the Document Status Information

check the document status information

curl -v -H 'Accept: application/vnd.gini.v1+json'
        -H 'Authorization: BEARER b6c470ffa-abf1-41aa-b866-cd3be0ee84f'
  'https://pay-api.gini.net/documents/b4bd3e80-7bd1-11e4-95ab-000000000000'

the response body will look similar to

{
  "_links": {
    "processed": "https:\/\/pay-api.gini.net\/documents\/b4bd3e80-7bd1-11e4-95ab-000000000000\/processed",
    "layout": "https:\/\/pay-api.gini.net\/documents\/b4bd3e80-7bd1-11e4-95ab-000000000000\/layout",
    "extractions": "https:\/\/pay-api.gini.net\/documents\/b4bd3e80-7bd1-11e4-95ab-000000000000\/extractions",
    "document": "https:\/\/pay-api.gini.net\/documents\/b4bd3e80-7bd1-11e4-95ab-000000000000"
  },
  "sourceClassification": "NATIVE",
  "origin": "UPLOAD",
  "progress": "PENDING",
  "creationDate": 1417710133864,
  "pageCount": 1,
  "name": "Document",
  "id": "b4bd3e80-7bd1lll-11e4-95ab-000000000000"
}

The document processing takes a bit of time and in order to get the extractions, you need to check the status of the processed document periodically. The status can have the value PENDING, which means that the document is being analyzed, and COMPLETED, which means that the document analysis is complete and the extractions are ready for retrieval. Check the current document status by sending a GET request to the URL that you received when the document was uploaded. Once the status changes to COMPLETED, the extractions are ready and you can retrieve them.

Retrieve the Extractions

retrieve the extractions

curl -v -H 'Accept: application/vnd.gini.v1+json'
    -H 'Authorization: BEARER b6c470ffa-abf1-41aa-b866-cd3be0ee84f'
    'https://pay-api.gini.net/documents/b4bd3e80-7bd1-11e4-95ab-000000000000/extractions'

The document extractions represent various document contents that the extraction system was able to understand and retrieve. In order to get all the extractions, send a request to the right (notice the API version v1).

example response

{
  "extractions": {
    "docType": {
      "value": "Invoice",
      "entity": "doctype",
    },
    "amountToPay": {
      "candidates": "amounts",
      "box": {
        "page": 1,
        "height": 9.0,
        "width": 30.870000000000005,
        "left": 524.13,
        "top": 357.89
      },
      "value": "12.00:EUR",
      "entity": "amount"
    },
    "paymentPurpose": {
      "box": {
        "page": 1,
        "height": 7.0,
        "width": 31.139999999999986,
        "left": 470.0,
        "top": 152.89
      },
      "value": "20980000",
      "entity": "text"
    },
    "iban": {
      "candidates": "ibans",
      "box": {
        "page": 1,
        "height": 7.0,
        "width": 38.920000000000016,
        "left": 470.0,
        "top": 143.89
      },
      "value": "DE74700500000000028273",
      "entity": "iban"
    },
    "paymentRecipient": {
      "box": {
        "page": 1,
        "height": 7.0,
        "width": 52.56000000000001,
        "left": 41.87,
        "top": 88.84
      },
      "value": "Deutsche Post AG",
      "entity": "companyname"
    }
  },
  "compoundExtractions": {
    "lineItems": [
      {
        "baseGross": {
          "entity": "amount",
          "value": "14.99:EUR",
          "box": {
            "top": 355.83,
            "left": 525.17,
            "width": 38.92000000000007,
            "height": 10.0,
            "page": 1
          }
        },
        "description": {
          "entity": "text",
          "value": "T-Shirt, black Size S",
          "box": {
            "top": 355.83,
            "left": 388.18,
            "width": 20.00999999999999,
            "height": 10.0,
            "page": 1
          }
        }
      },
      {
        "artNumber": {
          "entity": "text",
          "value": "10101",
          "box": {
            "top": 388.43,
            "left": 82.05,
            "width": 20.0,
            "height": 10.0,
            "page": 1
          }
        }
      }
    ]
  },
  "candidates": {
    "amounts": [
      {
        "box": {
          "page": 1,
          "height": 9.0,
          "width": 30.870000000000005,
          "left": 524.13,
          "top": 357.89
        },
        "value": "12.00:EUR",
        "entity": "amount"
      },
      {
        "box": {
          "page": 1,
          "height": 12.0,
          "width": 40.89999999999998,
          "left": 138.02,
          "top": 413.09
        },
        "value": "12.00:EUR",
        "entity": "amount"
      }
   ]
  }
}

The returned object contains specific extractions (a value with some specific semantic property), compound extractions (a group of values with some specific semantic property) as well as candidates (a list of values for some semantic property).

The example response (shortened, on the right) is an invoice (see docType) issued by Deutsche Post AG. The receiver of the invoice has to pay 12€ (see amountToPay). It contains one line item (see lineItem) with an article number 10101, a tax rate 19% and an amount 12€.

Send Feedback and Get Even Better Extractions Next Time

Feedback is an API request containing the correct extractions that you can send us in order to improve the future extraction accuracy of the system. In fact your application should always send at least some feedback. The more complete and qualitative the feedback is, the sooner the extraction system learns what is correct and what's not. Feedback is critical to us and important to you because there is no other way for us know in realtime whether the extraction system is delivering the best possible quality for your application.

In order to inform the system the extraction was correct or incorrect, send back the correct value in the feedback request. It is important that it should be the value exactly as it appears on the actual document (not calculated or inferred). Once the feedback is received it gets compared to the extracted value and the result is used futher in reports and is included into a self-learning mechanism of the Gini extraction system.

Overview of the Gini Pay API

This section provides general information about the Gini Pay API. If you want a step-by-step guide how to upload your first document and retrieve its semantic content, have a look at the getting started guide.

IPv6 Compatibility

IPv6 compatibility example

    $ host pay-api.gini.net
    pay-api.gini.net has address 46.245.182.123
    pay-api.gini.net has IPv6 address 2a00:14e0:600:1500:d0c5::7

    $ host user.gini.net
    user.gini.net has address 46.245.182.124
    user.gini.net has IPv6 address 2a00:14e0:600:1500:d0c5::2

Gini Pay API and User Center are accessible from legacy IPv4 and IPv6 networks. The protocol precedence depends on your operating system and configuration if both protocols are enabled.

Media Types

the media types consumed and produced by the Gini Pay API look like this

    application/vnd.gini.<version>+json

Custom media types are used in the API to let the consumers choose the version of the data format they wish to receive. This is done by adding one or more of the following media types to the Accept header when a request is made. media types are specific to resources, allowing them to change independently and supporting formats that other resources don't.

API Versions

Currently there is one stable version of the Gini Pay API. Future versions can be requested using a specific Accept header. This is primarily for testing new extractions but may affect other parts of the API as well.

Version 1 (v1)

v1 media type

    Accept: application/vnd.gini.v1+json

Gini Pay API v1 is stable and will remain backwards compatible. Please contact us via api@gini.net if you have any problems.

Developers are strongly encouraged to explicitly specify the required version of the Gini Pay API using the HTTP/1.1 Accept header (see the example) because by default the requests are treated as requests to version 1 (v1) of the API.

Authentication

Only authenticated users are allowed to make API requests. The Gini API uses the OAuth 2.0 protocol with bearer tokens for authentication from untrusted devices and a simplified authentication scheme for trusted devices / sytems (eg. backend or gateway) based on basic auth.

In order to use the API in your application, you first have to register your application with Gini. Afterwards your application should request an access token from the Gini Authorization Server and use it to access the Gini Pay API.

Security

The Gini Pay API is only accessible over HTTPS. Please make sure that your application validates the relevant X.509 certificates (e.g. common name matches hostname, issuing CA is trusted, etc.).

Client Errors

HTTP response codes

The API uses idiomatic HTTP status codes to indicate if a request was successful or not and whether it should be repeated.

Code Description
2xx The request was successful.
4xx The request was not successful. See the response body for details. Retrying with the same arguments will not work.
5xx Some error occurred while processing the request. Please try again.

Error Entity

error entity response

{
  "message": "Validation of the request entity failed",
  "requestId": "8896f9dc-260d-4133-9848-c54e5715270f"
}

In case of an error, the Gini Pay API always returns a JSON object with further information about the occurred error. The JSON object consists of the following properties:

Name Type Description
message string Human consumable error description (not intended for application end-users)
requestId string Unique ID identifying the request. Please provide this when contacting our support.

Documents

As the key aspect of the Gini Pay API is to provide information extraction for analyzing documents, the API is mainly built around the concept of documents. A document can be any written representation of information such as invoices, reminders, remittance slips and so on.

The main idea is that you submit a document in the form of an electronic file to Gini. After the document has been analyzed by Gini you can get the information that is extracted from the document by querying the API.

The following documentation explains those actions in more detail.

Submitting Files

documents can be submitted by doing a POST request to the /documents resource.

    POST /documents

In order to extract document information, the document source file must be first submitted to Gini.

Submitting documents is as easy as sending a POST request to the /documents resource path. After successful submission the location of the new document is returned in the Location header.

The Gini Pay API currently supports two different variants of uploads, one optimized for web applications running in a web browser and the other for all other types of clients.

The first variant optimized for web applications expects the documents to be uploaded using a multipart/form-data encoding method.

The second variant for all other clients simply uses the request body (independent of the request Content-Type) as the document.

Supported File Formats

Gini currently supports document files in PDF, GIF (non-animated), PNG, JPEG, TIFF as well as plain text formats. You can use native documents (PDF only) as well as scanned document (all other supported formats).

Note that there are certain limitations though:

The above applies both to single page documents as well as to each page in a multi-page document.

Document Uploading Schemes

The Gini API allows you to upload a document as a single file or in parts, page by page.

Upload a Single File Document

This is the standard way of uploading a document to the Gini extraction system. A PDF document can contain single or multiple pages. JPEG, PNG documents are also accepted. When it is uploaded, it is processed by the system normally and without any adjustments regarding its structure.

Request

upload a document

variant for web applications running in a web browser with access token:

curl -H 'Authorization: BEARER <token>'
    --form 'file=@file.pdf'
    -H 'Accept: application/vnd.gini.v1+json'
    -i https://pay-api.gini.net/documents

variant for all other types of applications:

curl -H 'Authorization: BEARER <token>'
    --data-binary '@file.pdf'
    -H 'Accept: application/vnd.gini.v1+json'
    -H 'Content-Type: application/pdf'
    -i https://pay-api.gini.net/documents?filename=file.pdf

or with X-User-identifier (see how to setup X-User-identifier):

curl -H 'X-User-Identifier: user1'
    --form 'file=@file.pdf'
    -H 'Accept: application/vnd.gini.v1+json'
    -u 'client-id:client-secret'
    -i https://pay-api.gini.net/documents
Headers
Header Value
Content-Type multipart/form-data; boundary=...
*/*
Accept application/vnd.gini.v1+json
x-document-metadata-branchid some customer specific id
x-document-metadata-deviceclass desktop_device or mobile_device

The x-document-metadata-* headers can be used to add some meta information to the upload. This information is used in analytics and reporting.

Requesting Query Parameters

If the upload is performed without multipart/form-data you can optionally provide a file name for the submitted document with a query parameter:

Name Type Description
filename string (Optional) File name of the submitted document.
Body

Only in case of Content-Type: multipart/form-data (applications running in a web browser):

Key Description
Content-Disposition form-data
file File contents of document.

Response

Headers
Status Code Description
201 (Created) Operation is successful.
Header Value
Content-Type application/vnd.gini.v1+json
Location Absolute URI (created document URI). Can be used to check progress and receive document information.
Errors
Status Code Description
400 (Bad Request) Returned when a file is sent in an invalid format.
401 (Unauthorized) Authorization credentials are either missing, wrong or outdated.
415 Content type is not supported.
503 Service unavailable. Please retry later.

Upload a Document Page by Page

Partial upload should be performed in two steps: a partial documents upload and a composite document upload. Keep in mind that you must complete Step 1 first before moving to Step 2!

Step 1 (Upload Each Page as a Partial Document)

Pages that are part of the document are referred to as partial documents. If you want to upload a page (or a page picture) that belongs to the document, your request header should additionally include Content-Type field with application/vnd.gini.v1.partial+png value or application/vnd.gini.v1.partial+pdf in case of PDF page.

Request

upload a partial document

variant for web applications running in a web browser with access token:

curl -H 'Authorization: BEARER <token>'
    --form 'file=@file.JPEG'
    -H 'Accept: application/vnd.gini.v1+json'
    -H 'Content-Type: application/vnd.gini.v1.partial+png'
    -i https://pay-api.gini.net/documents

variant for other types of applications with access token:

curl -H 'Authorization: BEARER <token>'
    --data-binary '@file.JPEG'
    -H 'Accept: application/vnd.gini.v1+json'
    -H 'Content-Type: application/vnd.gini.v1.partial+png'
    -i https://pay-api.gini.net/documents?filename=file.JPEG

or with X-User-identifier (see how to setup X-User-identifier):

curl -H 'X-User-Identifier: user1'
    --form 'file=@file.JPEG'
    -H 'Accept: application/vnd.gini.v1+json'
    -H 'Content-Type: application/vnd.gini.v1.partial+png'
    -u 'client-id:client-secret'
    -i https://pay-api.gini.net/documents

In order to upload a page picture or a partial document, specify a different content type:

Headers
Header Value
Content-Type multipart/form-data; boundary=...
*/*
Accept application/vnd.gini.v1+json
x-document-metadata-branchid some customer specific id
x-document-metadata-deviceclass desktop_device or mobile_device

The x-document-metadata-* headers can be used to add some meta information to the upload. This information is used in analytics and reporting.

Request Query Parameters
Name Type Description
filename string (Optional) File name of the submitted document.
Body

File contents of the document.

Response
Headers
Status Code Description
201 (Created) Operation is successful.
Header Value
Content-Type application/vnd.gini.v1+json
Location Absolute URI (created partial document URI) which should be referred by a composite document.
Errors
Status Code Description
400 (Bad Request) Returned when the sent file has invalid format.
401 (Unauthorized) Authorization credentials are either missing, wrong or outdated.
415 Content type is not supported.
503 Service unavailable. Please retry later.

Step 2 (Upload JSON as a Composite Document)

After successfully uploading all pages as partial documents, you should announce their locations to the extraction system. This is done by uploading a composite document which is a simple JSON file with corresponding locations of partial documents.

Request

upload a composite document

variant for web applications running in a web browser with access token:

curl -H 'Authorization: BEARER <token>'
    -H 'Accept: application/vnd.gini.v1+json'
    -H 'Content-Type: application/vnd.gini.v1.composite+json'
    -X POST -d'{...}'
    -i https://pay-api.gini.net/documents

or

curl -H 'Authorization: BEARER <token>'
    --data-binary '@data.json'
    -H 'Accept: application/vnd.gini.v1+json'
    -H 'Content-Type: application/vnd.gini.v1.composite+json'
    -i https://pay-api.gini.net/documents

or with X-User-identifier (see how to setup X-User-identifier):

curl -H 'X-User-Identifier: user1'
    -H 'Accept: application/vnd.gini.v1+json'
    -H 'Content-Type: application/vnd.gini.v1.composite+json'
    -u 'client-id:client-secret'
    -X POST - d'{...}'
    -i https://pay-api.gini.net/documents

with post body of

{
  "partialDocuments": [
    {
      "rotationDelta": 0,
      "document": "localtion of parital doc 1"
    },
    {
      "rotationDelta": 0,
      "document": "location of partial doc 2"
    },
    ...
  ]
}

location in form of https://pay-api.gini.net/documents/e8606210-56ed-11ea-b823-b351b84ae4b3

In order to upload a composite document which aggregates one or multiple partial documents, a different content type needs to be specified.

Headers
Header Value
Content-Type application/vnd.gini.v1.composite+json
Accept application/vnd.gini.v1+json
Request Query Parameters

If the upload is performed without multipart/form-data you can optionally provide a file name for the submitted document with a query parameter:

Name Type Description
filename string (Optional) File name of the submitted document.
Body

Raw bytes of the composite json.

Key Description
partialDocuments A list of partial documents (the location is returned after the partial documents are successfully uploaded).
Response
Headers
Status Code Description
201 (Created) Operation is successful.
Header Value
Content-Type application/vnd.gini.v1+json
Location Absolute URI of created document (document URI) to check progress and getting document information.
Errors
Status Code Description
400 (Bad Request) Returned when a file in an invalid format is sent
401 (Unauthorized) Authorization credentials are either missing, wrong or outdated.
415 content type not supported.
503 Service unavailable. Please retry later.

Checking Processing Status and Getting Document Information

document information can be retrieved by sending a GET request to the document URI.

    GET /documents/{id}

Once the document is submitted and processed you can check its processing status by examining the document information. It can be retrieved with a GET request containing the document URI. When the document has been processed you can retrieve its extractions and layout.

Request

get document processing status

curl -H 'Authorization: BEARER <token>'
    -X GET -H 'Accept: application/vnd.gini.v1+json'
    -i https://pay-api.gini.net/documents/c292af40-d06a-11e2-9a2f-000000000000
Headers
Header Value
Accept application/vnd.gini.v1+json

Response

request response

{
  "id": "626626a0-749f-11e2-bfd6-000000000000",
  "creationDate": 1360623867402,
  "name": "scanned.jpg",
  "progress": "COMPLETED",
  "origin": "UPLOAD",
  "sourceClassification": "SCANNED",
  "pageCount": 1,
  "_links": {
    "extractions": "https://pay-api.gini.net/documents/626626a0-749f-11e2-bfd6-000000000000/extractions",
    "layout": "https://pay-api.gini.net/documents/626626a0-749f-11e2-bfd6-000000000000/layout",
    "document": "https://pay-api.gini.net/documents/626626a0-749f-11e2-bfd6-000000000000",
    "processed": "https://pay-api.gini.net/documents/626626a0-749f-11e2-bfd6-000000000000/processed"
  }
}
Headers
Status Code Description
200 (OK) Operation is successful.
Header Value
Content-Type application/vnd.gini.v1+.json
Body (application/vnd.gini.v1+json)
Key Child Key Type Description
id string Document qnique identifier (such as UUID Version 1).
name string Document name (as stated in upload).
pageCount number Number of pages.
creationDate number Document creation unix timestamp (in milliseconds).
origin string Document source channel: UPLOAD (if uploaded via Gini Pay API) or UNKNOWN.
progress string Document processing status: PENDING, COMPLETED or ERROR.
sourceClassification string Classification of the source file: SCANNED, SANDWICH, NATIVE or TEXT.
pageNumber number Document page number.
images object Pre-rendered page image URIs.
_links array List of related resources, e.g. found extractions or document layout.
extractions string Document extractions URI
layout string Document layout URI.
processed string Processed document URI.
document string Document URI.

Errors

Status Code Description
404 (Not Found) Returned when no document can be found under specific URI.

Retrieving Extractions

extractions can be retrieved by performing a GET request with the extractions URI:

    GET /documents/{id}/extractions

Once the document is processed, the document extractions become available for retrieval. See document extractions for more details.

Request

get extractions

curl -H 'Authorization: BEARER <token>'
    -X GET -H 'Accept: application/vnd.gini.v1+json'
    -i https://pay-api.gini.net/documents/c292af40-d06a-11e2-9a2f-000000000000/extractions
Headers
Header Value
Accept application/vnd.gini.v1+json

Response

example response

{
   "extractions": {
       "amountToPay": {
           "box": {
               "height": 9.0,
               "left": 516.0,
               "page": 1,
               "top": 588.0,
               "width": 42.0
           },
           "entity": "amount",
           "value": "24.99:EUR",
           "candidates": "amounts"
       }
     },
     "candidates": {
       "amounts": [
         {
             "box": {
                 "height": 9.0,
                 "left": 516.0,
                 "page": 1,
                 "top": 588.0,
                 "width": 42.0
             },
             "entity": "amount",
             "value": "24.99:EUR"
         },
         {
             "box": {
                 "height": 9.0,
                 "left": 241.0,
                 "page": 1,
                 "top": 588.0,
                 "width": 42.0
             },
             "entity": "amount",
             "value": "21.0:EUR"
         }
       ]
       ...
   }
}

example response with Return Assistant specific extractions

{
    "extractions": {
        "amountToPay": {
            "box": {
                "height": 9,
                "left": 516,
                "page": 1,
                "top": 588,
                "width": 42
            },
            "entity": "amount",
            "value": "24.99:EUR",
            "candidates": "amounts"
        },
        "amountsAreConsistent": {
            "entity": "text",
            "value": "true"
        },
        "shipment-addon": {
            "entity": "amount",
            "value": "5.00:EUR"
        },
        "discount-addon": {
            "entity": "amount",
            "value": "-5.00:EUR"
        },
        "giftcard-addon": {
            "entity": "amount",
            "value": "1.00:EUR"
        },
        "other-discounts-addon": {
            "entity": "amount",
            "value": "-1.00:EUR"
        },
        "other-charges-addon": {
            "entity": "amount",
            "value": "1.00:EUR"
        }
    },
    "compoundExtractions": {
        "lineItems": [
            {
                "artNumber": {
                    "value": "10101",
                    "entity": "text",
                    "box": {
                        "height": 7,
                        "left": 55,
                        "page": 1,
                        "top": 546,
                        "width": 100
                    }
                },
                "quantity": {
                    "value": "12",
                    "entity": "numeric"
                }
            },
            {
                "artNumber": {
                    "value": "10103",
                    "entity": "text"
                },
                "quantity": {
                    "value": "3",
                    "entity": "numeric"
                }
            }
            ...
        ]
    },
    "returnReasons": [ ... ],
    "candidates": {
        "amounts": [ ... ]
    }
}
Headers
Status Code Description
200 (OK) Operation is successful.
Header Value
Content-Type application/vnd.gini.v1+json
Body (application/vnd.gini.v1+json)

A detailed explanation of the response format can be found in extractions section.

Name Type Description
extractions object Labels to extractions mapping (i.e. specific-extractions).
candidates object A mapping of labels to a list of extraction-candidates.

Errors

Status Code Description
404 (Not Found) Requested entity couldn't be found.

Submitting Feedback on Extractions

Feedback are user approved or corrected extraction values that are submitted by you back to the extraction system.

You should always submit the feedback on extractions. The feedback that is correctly submitted allows Gini to measure the extraction quality in order to provide the best possible user experience. Moreover, it helps us to continuously improve the extraction system and perform valuable data analytics for you.

Gini employs various machine learning techniques in order to learn from feedback automatically. Therefore, it is equally important for Gini to receive both feedback on correct and on incorrect extractions.

There are currently two ways to submit the feedback.

The first and the most common one is to submit the complete feedback in one request. This is the easiest way if your frontend (application) displays the extractions on a screen in an editable form. A user can modify the extractions before pressing the confirmation button.

The second (a rare use case) is where the final approvement signal (button click) is not possible. In such case you can send the feedback on one label per request.

There are three different types of feedback:

Please see detailed examples next.

Submitting Feedback on Extractions

submitting feedback on extractions


    PUT /documents/{id}/extractions/feedback

The Gini Pay API allows you to submit the feedback on multiple extractions for a single document with a single request. It is strongly recommended that you submit your feedback in this way for two reasons. On the one hand, the total number of round trips is reduced to one and the feedback is handled internally as a batch. Therefore, the update is more efficient for multiple extractions compared to submitting the feedback with each separate request (see single feedback). On the other hand, Gini's machine learning training techniques can benefit from the feedback on multiple extractions since Gini will be aware of the fact that single parts of the submitted feedback belong together.

Request

Example

We show a more elaborated example here in order to explain different types of the feedback. The example scenario is as follows: the user uploads a document where the labels amountToPay, paymentReference, iban are extracted. Unfortunately the label paymentRecipient could not be extracted. The response to the extractions request is as follows:

{
    "candidates": {
    },
    "extractions": {
        "amountToPay": {
            "box": {
                "height": 8.0,
                "left": 545.0,
                "page": 1,
                "top": 586.0,
                "width": 17.0
            },
            "candidates": "amounts",
            "entity": "amount",
            "value": "5.60:EUR"
        },
        "iban": {
            "box": {
                "height": 7.0,
                "left": 447.0,
                "page": 1,
                "top": 746.0,
                "width": 100.0
            },
            "candidates": "ibans",
            "entity": "iban",
            "value": "DE68130300000017850360"
        },
        "paymentReference": {
            "entity": "reference",
            "value": "ReNr 123, KdNr 32"
        }
    },
    "compoundExtractions": {
        "lineItems": [
            {
              "artNumber": {
                "value": "10101",
                "entity": "text" ,
                "box": {
                    "height": 7.0,
                    "left": 55.0,
                    "page": 1,
                    "top": 546.0,
                    "width": 100.0
                }
              },
              "quantity": {
                "value": "12",
                "entity": "numeric"
              }
            },
            {
              "artNumber": {
                "value": "10103",
                "entity": "text"
              },
              "quantity": {
                "value": "3",
                "entity": "numeric"
              }
            }
        ]
    }
}

The user adds missing paymentRecipient value (complementary feedback) and corrects the paymentReference to "ReNr 1735, KdNr 37" (negative feedback). Sets the quantity of one line item to 0 and adds a reason for returning the articles. The iban, amountToPay and the remaining part of lineItems are correct (positive feedback). The document is not shown, so we can leave out the boxes. Then the resulting feedback request is as follows:

{
   "extractions": {
       "amountToPay": {
           "value": "5.60:EUR"
       },
       "iban": {
           "value": "DE68130300000017850360"
       },
       "paymentReference": {
           "value": "ReNr 1735, KdNr 37"
       },
       "paymentRecipient": {
           "value": "Zalando SE"
       }
   },
 "compoundExtractions": {
        "lineItems": [
            {
              "artNumber": {
                "value": "10101"
              },
              "quantity": {
                "value": "0"
              },
              "returnReason": {
                "value": "r3"
              }
            },
            {
              "artNumber": {
                "value": "10103"
              },
              "quantity": {
                "value": "3"
              }
            }
        ]
    }
}

Give feedback and correct or verify multiple specific labeled extraction patterns with a single PUT or POST request to the document extractions URI.

The labels must correspond to the names of the extraction types e.g. amountToPay. See available specific extractions for possible values.

Headers
Header Value
Content-Type application/vnd.gini.v1+json
Body
Key Type Description
extractions object Feedback on atomic extractions
compoundExtractions object Feedback on compound extractions

Response

Status Code Description
204 (No Content) The feedback was successfully processed.
404 (Not Found) The document or the label could not be found.
406 (Not Acceptable) The request headers were not set correctly.
422 (Unprocessable Entity) At least one value was not valid regarding entity validation rules of the label.

Test Example

In order to test the integration of the feedback functionality, we offer a PDF test document with the expected outcome in a JSON format. This document can be used for an integration test of Gini’s Pay API in general. Furthermore, we provide a query for sending feedback where all fields are correct except for the amountToPay. After sending this feedback we show you how you can ensure that the feedback with your confirmation and correction for the field values was successful.

{
   "feedback": {
       "amountToPay": {
           "value": "950.00:EUR"
       },
       "iban": {
           "value": "DE68130300000017850360"
       },
       "bic": {
           "value": "BYLADEM1001"
       },
       "paymentPurpose": {
           "value": "RE-20170512-02"
       },
       "paymentRecipient": {
           "value": "Fahrrad Rückenwind"
       }
   }
}

Submitting Feedback on Invalid Extractions

submitting feedback on invalid extractions

    DELETE /documents/{id}/extractions/{label}

Request

In case an extraction was erroneously found (i.e. not present in the source document), you can delete it by issuing a DELETE request to the extraction URI:

Response

Status Code Description
204 (No Content) Label removal was successful.
404 (Not Found) The document or the label could not be found.

Retrieving Document Pages

retrieving document pages

    GET /documents/{id}/pages

The Gini Accounting API renders preview images of the document pages. In order to retrieve a list of pages for a document, issue a GET request to the pages sub-resource of the document.

Request

Path Parameters

retrieve document pages

curl -H 'Authorization: BEARER <token>'
    -X GET -H 'Accept: application/vnd.gini.v1+json'
    -i https://pay-api.gini.net/documents/c292af40-d06a-11e2-9a2f-000000000000/pages
Name Value
id Document ID
Headers
Header Value
Accept application/vnd.gini.v1+json

Response

the response will be a list of pages.

[
  {
    "images" : {
      "large" : "https://pay-api.gini.net/documents/c292af40-d06a-11e2-9a2f-000000000000/pages/1/large",
      "medium" : "https://pay-api.gini.net/documents/c292af40-d06a-11e2-9a2f-000000000000/pages/1/medium"
    },
    "pageNumber" : 1
  },
  {
    "pageNumber" : 2,
    "images" : {
      "large" : "https://pay-api.gini.net/documents/c292af40-d06a-11e2-9a2f-000000000000/pages/2/large",
      "medium" : "https://pay-api.gini.net/documents/c292af40-d06a-11e2-9a2f-000000000000/pages/2/medium"
    }
  }
]
Headers
Status Code Description
200 (OK) The request was successful.
404 (Not Found) The requested document does not exist.
Body
Name Type Description
pages array All pages in the current result page.

A page is an entity with the following fields:

Key Child key Type Description
documentId string UUID of the document which the page belongs to.
pagenum number Page number.
_links object Links to related resources.
document string Link to the document to which the page belongs.
pages string Link to the pages of the document.
_images object Links to pre-rendered page images in different resolutions.
image resolution in pixels string Link to a pre-rendered image of the page.

Retrieving the Layout of a Document

The layout of the document describes the textual content of a document with positional information, based on the processed document.

Request

retrieving a layout of the document


    GET /documents/{id}/layout

Example

curl -H 'Authorization: BEARER <token>'
    -X GET -H 'Accept: application/vnd.gini.v1+json'
    -i https://pay-api.gini.net/documents/c292af40-d06a-11e2-9a2f-000000000000/layout

The layout of the document can be retrieved by a GET request to the layout URI:

Headers
Header Value
Accept application/vnd.gini.v1+json

Response

layout example

{
  "pages": [
    {
      "number": 1,
      "sizeX": 595.3,
      "sizeY": 841.9,
      "textZones": [
        {
          "paragraphs": [
            {
              "l": 54.0,
              "t": 158.76,
              "w": 190.1,
              "h": 36.55000000000001,
              "lines": [
                {
                  "l": 54.0,
                  "t": 158.76,
                  "w": 190.1,
                  "h": 10.810000000000002,
                  "wds": [
                    {
                      "l": 54.0,
                      "t": 158.76,
                      "w": 18.129999999999995,
                      "h": 9.900000000000006,
                      "fontSize": 9.9,
                      "fontFamily": "Arial-BoldMT",
                      "bold":false,
                      "text": "Ihre"
                    },
                    {
                      "l": 74.86,
                      "t": 158.76,
                      "w": 83.91000000000001,
                      "h": 9.900000000000006,
                      "fontSize": 9.9,
                      "fontFamily": "Arial-BoldMT",
                      "bold":false,
                      "text": "Vorgangsnummer"
                    },
                    {
                      "l": 158.76,
                      "t": 158.76,
                      "w": 3.3000000000000114,
                      "h": 9.900000000000006,
                      "fontSize": 9.9,
                      "fontFamily": "Arial-BoldMT",
                      "bold":false,
                      "text": ":"
                    },
                    [...]
                  ]
                },
                [...]
              ]
            }
          ]
        }
      ],
      "regions": [
        {
          "l": 20.0,
          "t": 240.1,
          "w": 190.0,
          "h": 150.3,
          "type": "RemittanceSlip"
        },
        [...]
      ]
    },
    [...]
  ]
}
Headers
Status Code Description
200 (OK) Operation is successful.
Header Value
Content-Type application/vnd.gini.v1+json
Body (application/vnd.gini.v1+json)
Key Type Description
pages array Array of page objects.
Page Object
Key Type Description
number number Number of the page starting with 1.
sizeX number Width of the page.
sizeY number Height of the page.
textZones array Array of textzone objects.
regions array Array of region objects.
TextZone Object
Key Type Description
paragraphs array Array of paragraph objects
Paragraph Object
Key Type Description
w number Width of the paragraph.
h number Height of the paragraph.
t number Distance of the paragraph from the upper edge of the page.
l number Distance of the paragraph from the left edge of the page.
lines array Array of line objects.
Line Object
Key Type Description
w number Width of the line.
h number Height of the line.
t number Distance of the line from the upper edge of the page.
l number Distance of the line from the left edge of the page.
wds array Array of word objects.
Word Object
Key Type Description
h number Height of the word.
w number Width of the word.
l number Distance of the word from the left edge of the page.
t number Distance of the word from the upper edge of the page.
fontSize number Font size of the word in points.
fontFamily string Name of the font family of the word.
bold boolean Indicates bold font style.
text string Text of word.
Region Object
Key Type Description
h number Height of the region of interest.
w number Width of the region of interest.
l number Distance of the region from the left edge of the page.
t number Distance of the region from the upper edge of the page.
type string Type of the region of interest, e.g. RemittanceSlip.

Errors

Status Code Description

404 (Not Found) The requested layout is invalid.

Retrieving the Processed Document

Request

retrieve the processed document

    GET /documents/{id}/processed

Before Gini tries to extract the information, it preprocesses the document, performing page deskewing, homography transformation, etc. The processed document can be retrieved by a GET request:

Path parameters

Name Value
id Document ID

Response

Headers

Status Code Description
200 (OK) Operation is successful.

Body

The version of the uploaded document file after preprocessing (color corrected, deskewed) which has been used for all layout and semantic extractions. In case of native PDF documents it is identical to the original document file.

Errors

Status Code Description
404 (Not Found) The requested document does not exist.

Deleting Documents

delete documents


    DELETE /documents/{id}

If you want to delete a document you can do this by sending a DELETE request to the document URI. When the document is deleted all associated resources (extractions, layout) will be deleted as well.

Request

delete request

curl -H 'Authorization: BEARER <token>'
    -X DELETE -i https://pay-api.gini.net/documents/c292af40-d06a-11e2-9a2f-000000000000

Delete the document by sending a DELETE request to the document URI.

Response

Headers

Status Code Description
204 (No Content) Operation is successful.

Errors

Status Code Description
404 (Not Found) Returned when no document can be found under the specific URI.

Getting a List of All Documents

get a list of all documents

    GET /documents

In order to get the list of all documents, send a GET request to the /documents resource. The response will contain a paginated list of all documents.

Request Query Parameters

example request

curl -H 'Authorization: BEARER <token>'
    -H 'Accept: application/vnd.gini.v1+json'
    -X GET -i https://pay-api.gini.net/documents?limit=50
Name Type Description
limit number (Optional) Maximum number of documents to return (default 20).
offset number (Optional) Starting offset (default 0).

Response

example response

{
  "documents": [
    {...},
    {...},
    ...
  ]
}

The response will contain a paginated list of documents.

Headers
Status Code Description
200 (OK) Operation is successful.
Body

The response entity has the following fields:

Name Type Description
documents array All documents of the current result page.

Document Extractions for Payment

The Payment API extracts payment information from invoices which can be used for SEPA transactions.

The Gini extraction system is able to extract this information and provide it in a structured form accessible through its Pay API. From now on we shall refer to such data as the document extractions.

Extractions

Extraction

{
  "entity": "amount",
  "value": "20.00:EUR",
  "box": { ... }
}

An extraction contains an entity which describes a general semantic type of the extraction (e.g. a iban, an bic, an amount). The entity also determines the format of the value containing text information. There may be an optional box element describing the position of the extraction value on the document. We refer to it as the bounding box. In most cases the extractions without a bounding box are considered to be meta information such as doctype.

Name Type Description
entity string Key (primary identification) of an entity type (e.g. iban). See available extraction entities for possible values.
value string A normalized textual representation of the Text/Information provided by the extraction value (e.g. iban without spaces between the digits).
box bounding-box (Optional) bounding box containing the position of the extraction value on the document.

Specific Extractions

specific extractions

{
  "amountToPay": {
      "entity": "amount",
      "value": "20.00:EUR",
      "box": { ... },
      "candidates": "amounts"
  }
}

specific Return Assistant extractions

{
    "amountsAreConsistent": {
        "entity": "text",
        "value": "true"
    },
    "shipment-addon": {
        "entity": "amount",
        "value": "5.00:EUR"
    },
    "discount-addon": {
        "entity": "amount",
        "value": "-5.00:EUR"
    },
    "giftcard-addon": {
        "entity": "amount",
        "value": "1.00:EUR"
    },
    "other-discounts-addon": {
        "entity": "amount",
        "value": "-1.00:EUR"
    },
    "other-charges-addon": {
        "entity": "amount",
        "value": "1.00:EUR"
    }
}

A specific extraction assigns a semantic property to the extraction. It also has an additional candidates field:

Name Type Description
candidates string (Optional) A reference to extraction candidates. See available extraction candidates for possible values.

Available Specific Extractions

Name Description Entity Candidates
amountToPay The amount which yet to be paid. amount amounts
bic The bic of a payment recipient. bic bics
docType The document type of a given document. doctype n/a
iban The IBAN of a document sender. iban ibans
paymentPurpose The payment purpose text text n/a
paymentRecipient The payment recipient, beneficiary of a money transfer activity companyname paymentRecipients
paymentReference The payment reference. reference n/a
amountsAreConsistent (Return Assistant) A special extraction to check the correctness of the line item values. amounts_are_consistent n/a
shipment-addon (Return Assistant) The amount of a shipment cost. amount n/a
discount-addon (Return Assistant) The amount of a discount. amount n/a
giftcard-addon (Return Assistant) The amount of a discount issued in a form of a giftcard. amount n/a
other-discounts-addon (Return Assistant) The total sum of all additional discounts. amount n/a
other-charges-addon (Return Assistant) The total sum of all additional charges. amount n/a

Return Assistant Extractions

The extraction system delivers additional extractions if the Return Assistant (Return Calculator) is activated for your application. The Return Assistant is an additional feature of the payment product which helps the payment users to select and return ordered goods by recognizing purchased items.

If the Return Assistant feature is activated for your application, the Gini extraction system will additionally deliver compound extractions and the Return Assistant specific extractions.

The correct functionality of the Return Assistant UI components of our Gini Bank SDK relies on the availability of these additional specific extractions. In other words, in addition to the compound extractions the Return Assistant specific extractions should not be filtered out or removed (if present) from the extractions delivered by the extraction system.

Available Compound Extractions

A Compound Extraction describes a group of extractions. It represents the line items recognized on an invoice and is delivered by the extraction system provided the Return Assistant feature is activated.

compound extractions example

{
 "compoundExtractions": {
     "lineItems": [
       {
         "baseGross": {
           "entity": "amount",
           "value": "19.99:EUR",
           "box": {
             "top": 355.83,
             "left": 525.17,
             "width": 38.92000000000007,
             "height": 10.0,
             "page": 1
           }
         },
         "description": {
           "entity": "text",
           "value": "T-Shirt black, XL",
           "box": {...
           }
         },
         "quantity": {
           "entity": "number",
           "value": "2",
           "box": {...
           }
         }
       },
       {
         "artNumber": {
           "entity": "text",
           "value": "kWh",
           "box": {...
           }
         },
         "baseGross": {
           "entity": "amount",
           "value": "14.99:EUR",
           "box": {...
           }
         },
         "description": {
           "entity": "text",
           "value": "Socks, white 43-46",
           "box": {...
           }
         }
       }
     ]
   }
}
Name Description Children Children Description Entity
lineItems Invoice line items describe the details of purchased items. artNumber article number text
baseGross gross amount of 1 unit amount
description description of the item text
position position of the item text
quantity quantity in the units of the item numeric

Return Reasons

In addition to line-items, the extraction system delivers a set of return reasons. A return reason represents a possible reason for the return of a line-item and its subsequent refund that a user have to choose during selection/deselection of the line-item. The delivered reasons will depend on the domain of the retailer, i.e. they will different depending on whether it's a fashion or a tech shop.

return reasons example

{
  "extractions": {
    "...": "..."
  },
  "compoundExtractions": {
    "...": "..."
  },
  "candidates": {
    "...": "..."
  },
  "returnReasons": [
    {
      "de": "Anders als im Bild",
      "en": "Looks different from site image",
      "id": "r1"
    },
    {
      "de": "Schlechte Qualität",
      "en": "Poor quality",
      "id": "r2"
    },
    {
      "de": "Defekt",
      "en": "Defect",
      "id": "r3"
    },
    {
      "de": "Passt nicht richtig",
      "en": "Doesn't suit me",
      "id": "r4"
    },
    {
      "de": "Falsches Produkt empfangen",
      "en": "Received wrong item",
      "id": "r5"
    },
    {
      "de": "Paket wurde beschädigt",
      "en": "Parcel was damaged",
      "id": "r6"
    },
    {
      "de": "Lieferung zu spät angekommen",
      "en": "Arrived too late",
      "id": "r7"
    }
  ]
}

Extraction Candidates

Extraction candidates represent a list of suggestions for an appropriate extraction.

Available Extraction Candidates

extraction candidates

{
    "dates": [
      {"entity": "amount","value": "20.00:EUR","box": { ... } },
      {"entity": "amount","value": "17.99:EUR","box": { ... } },
      ...
    ]
}
Name Description Entity
amounts All amounts of a given document. amount
bics All BICs of a given document. bic
ibans All IBANs of a given document. iban
referenceIds All potential reference id numbers of a given document. text

Extraction Entities

Available extraction entities list (follow each link for a detailed description):

Bounding Box

Bounding Box

{
    "box": {
      "page": 2,
      "left": 483.0,
      "top": 450.0,
      "width": 51.0,
      "height": 9.0
    }
}

A bounding box creates a direct relation between an extraction and a document. The box describes the page and the position where the extraction originates from.

Name Type Description
left number The distance from the left edge of the page
top number The distance from the top edge of the page
width number The horizontal dimension of a box
height number The vertical dimension of a box
page number The page on which the box can be found, starting with 1

Coordinate System

The origin of the coordinate system is adjusted to the upper left corner of the page. The coordinate system uses the DTP point as unit: 1 pt = 1 inch / 72 = 25.4 mm / 72 = 0.3528 mm.

Extraction Confidence

confidence example

{
    "entity": "recipient",
    "value": "Max Mustermann Musterstrasse 1 Musterstadt",
    "box": {
        "top": 379.0,
        "left": 68.0,
        "width": 244.0,
        "height": 10.0,
        "page": 1
    },
    "confidence": 0.955
}

Entity Reference

amount

amount

{
    "entity": "amount",
    "value": "33.78:EUR",
    "box": {
        "page": 1,
        "left": 535.0,
        "top": 395.0,
        "width": 25.0,
        "height": 10.0
    }
}

Describes an amount of money with a specific currency in the format <Amount>:<Currency Code>, where <Amount> is a decimal number with "." as decimal separator and ":" as delimiter between <Amount> and <Currency Code>.

The currency code must be given according to the list specified in ISO 4217.

Format
Name Type Description
entity string Must be amount.
value string Amount in the defined format.
box bounding-box Bounding box of the occurrence including the page number.
Valid Feedback
Form Example
<Number>:<Currency Code/Symbol> 12.3:EUR; 12,4:USD; 12.98:USD

<Number> <Currency Code/Symbol> (1-space-separation) 12,3 EUR; 12,4 USD; 12 € <Currency Code/Symbol> <Number> (1-space-separation) EUR 12.3; \$ 12.4

bic

Describes a BIC number.

bic

{
    "entity": "bic",
    "value": "GENODEF1HH2",
    "box": {
        "page": 1,
        "left": 506.0,
        "top": 777.0,
        "width": 53.0,
        "height": 6.0
    }
}
Format
Name Type Description
entity string Must be bic.
value string BIC number in the normalized form (without spaces between digits and letters).
box bounding-box Bounding box of the occurrence including the page number.
Valid Feedback
Form Example
String matching BIC format GENODEF1HH2

companyname

companyname

{
    "entity": "companyname",
    "value": "Weinquelle Lühmann",
    "box": {
        "page": 1,
        "left": 535.0,
        "top": 395.0,
        "width": 25.0,
        "height": 10.0
    }
}

Describes a (sender) company name.

Format
Name Type Description
entity string Must be companyname.
value string The company name.
box bounding-box Bounding box of the occurrence including the page number.
Valid Feedback
Form Example
Random string with at least 2 letter/digit characters O2, BMW, ABC GmbH

A string with a single letter/digit character will be rejected.

currency

currency

{
    "entity": "currency",
    "value": "EUR",
    "box": {
        "page": 1,
        "left": 535.0,
        "top": 395.0,
        "width": 25.0,
        "height": 10.0
    }
}

Describes the currency of the document.

The currency code must be given according to the list specified in ISO 4217.

Format
Name Type Description
entity string Must be currency.
value string Currency in the defined format.
box bounding-box Bounding box of the occurrence including the page number.
Valid Feedback
Form Example

Euro currency symbol € Euro Currency name/code | EUR, EURO

Since only German documents are supported at the moment, the following strings are allowed: €, EUR, EURO

Document Types

doctype

{
    "entity": "doctype",
    "value": "Invoice"
}

Describes a document type. A list of supported document types:

Format
Name Type Description
entity string Must be doctype.
value string The document type.
Valid Feedback
Form Example
One of the above listed values Invoice, Reminder

iban

iban

{
    "entity": "iban",
    "value": "DE74700500000000028273",
    "box": {
        "page": 1,
        "left": 425.0,
        "top": 770.0,
        "width": 83.0,
        "height": 6.0
    }
}

Describes an IBAN.

Format
Name Type Description
entity string Must be iban.
value string IBAN in the normalized form (without spaces between digits and letters).
box bounding-box Bounding box of the occurrence including the page number.
Valid Feedback
Form Example
Valid IBAN DE68700202700667302269

Invalid IBAN will be rejected.

numeric

numeric

{
    "entity": "numeric",
    "value": "12.5",
    "box": {
        "page": 1,
        "left": 429.0,
        "top": 133.0,
        "width": 53.0,
        "height": 8.0
    }
}

Describes a numeric value (integer/float).

Format
Name Type Description
entity string Must be numeric.
value string Numeric value in string.
box bounding-box Bounding box of the occurrence including the page number.
Valid Feedback
Form Example
A string of integer or float 1, 1.5, 1.234

paymentReference

reference

{
    "entity": "reference",
    "value": "K19218331",
    "box": {
        "page": 1,
        "left": 535.0,
        "top": 395.0,
        "width": 25.0,
        "height": 10.0
    }
}

Describes a payment reference.

Format
Name Type Description
entity string Must be reference.
value string The payment reference with ", " as delimiter between reference parts.
box bounding-box Bounding box of the occurrence including the page number.
Valid Feedback
Form Example
A string with length >= 5 This a reference.

A string with less than 5 non space characters will be rejected.

amounts_are_consistent

amountsAreConsistent is a special extraction introduced for the Return Assistant front-end. This extraction text value is set to "true" whenever we are confident that the delivered line-item amounts, discounts and other additional costs are extracted correctly. When the extraction value is "false", the Return Assistant screen should not appear and the compound extractions will be removed from the response (this behavior is subject to change in the future).

amounts_are_consistent

{
  "entity" : "text",
  "value": "true",
  "box" : {}
}
Format
Name Type Description
entity string Must be text.
value string Either "true" or "false".
box bounding-box n/a.

returnreason

returnreason

{
    "entity": "returnreason",
    "value": "r3"
}

Sets the return reason for a given line item.

Format
Name Type Description
entity string Must be returnreason.
value string The code of the return reason.
Valid Feedback
Form Example
String containing the return reason code r3

A string not containing a valid return reason code will be rejected.

text

text

{
    "entity": "text",
    "value": "Aktenzeichen: K19218331",
    "box": {
        "page": 1,
        "left": 535.0,
        "top": 395.0,
        "width": 25.0,
        "height": 10.0
    }
}

Describes a plain text entity.

Format
Name Type Description
entity string Must be text.
value string Plain text.
box bounding-box Bounding box of the occurrence including the page number.
Valid Feedback

Generally Text entity accepts all kinds of Text as feedback except for some specific fields which the extra rules are applied to.

Label Form Example
branchId digit sequence 12345, 678901234
transactionId
paymentMethod one of the allowed valid payment methods Cash, Card, Contactless Card, Girocard, Contactless Girocard, Contactless Visa, Contactless Mastercard

Payments

The Gini Pay API provides the service of hands over and resolves payment requests. A payment request is created by an invoicing party and is resolved by a payment provider.

Getting a list of payment providers

A payment provider is a Gini partner which integrated the GiniPay for Banks SDK into their mobile apps for Android or iOS. The GiniPay for Banks SDK allows to receive and resolve payment requests and integrates with the payment functionality of the banking app. The GiniPay for Banks SDK uses deep links to handle payments.

Payment providers are handled by Health API. Authentication in Health API is identical to authentication in Pay API (see Authentication in Pay API). Expected header is application/vnd.gini.v3+json instead of application/vnd.gini.v1+json used in Pay API.

get the list

GET /paymentProviders
Host: health-api.gini.net
Authorization: BEARER c796535e-32e4-11eb-b966-e30e07dee3dc
Accept: application/vnd.gini.v3+json

yields a list of payment provider objects

[
  {
    "id": "7e72441c-32f8-11eb-b611-c3190574373c",
    "name": "ING-DiBa",
    "appSchemeIOS": "ginipay_ingdiba",
    "packageNameAndroid": "com.example.bank",
    "minAppVersion" : {
      "ios": "4.3.2",
      "android": "3.5.1"
    }
  },
  {
    "id": "9a9b41f2-32f8-11eb-9fb5-e378350b0392",
    "name": "Deutsche Bank",
    "appSchemeIOS": "ginipay_ingdiba",
    "packageNameAndroid": "com.example.bank",
    "minAppVersion" : {
      "ios": "7.7.2",
      "android": "6.9.1"
    }
  },
  ...
]
Response

List of payment provider objects:

Key Description
id the id of the payment provider
name the name of the payment provider
minAppVersion object containing the minimal required app versions per platform
appSchemeIOS the uri scheme for query the banking app for iOS
packageNameAndroid the unique package name of the banking app

Getting a Payment Provider

get the payment provider

GET /paymentProviders/7e72441c-32f8-11eb-b611-c3190574373c
Host: health-api.gini.net
Authorization: BEARER c796535e-32e4-11eb-b966-e30e07dee3dc
Accept: application/vnd.gini.v3+json

yields the payment provider object

{
  "id": "7e72441c-32f8-11eb-b611-c3190574373c",
  "name": "ING-DiBa",
  "appSchemeIOS": "ginipay_ingdiba",
  "packageNameAndroid": "com.example.bank",
  "minAppVersion" : {
    "ios": "4.3.2",
    "android": "3.5.1"
  }
}
Response
Key Description
id the id of the payment provider
name the name of the payment provider
minAppVersion object containing the minimal required app versions per platform
appSchemeIOS the uri scheme for query the banking app for iOS
packageNameAndroid the unique package name of the banking app

Creating Payment Requests

Payment Requests are handled via Health API using header application/vnd.gini.v3+json

create a payment request

POST /paymentRequests HTTP/1.1
Host: health-api.gini.net
Authorization: BEARER c796535e-32e4-11eb-b966-e30e07dee3dc
Content-Type: application/vnd.gini.v3+json

with

{
  "sourceDocumentLocation": "https://health-api.gini.net/documents/88090c5a-32ed-11eb-9e1a-9f2bc4656a7d",
  "paymentProvider": "9a9b41f2-32f8-11eb-9fb5-e378350b0392",
  "recipient": "Dr. med. Hackler",
  "iban": "DE02300209000106531065",
  "bic": "CMCIDEDDXXX",
  "amount": "335.50:EUR",
  "purpose": "ReNr AZ356789Z"
}

response

HTTP/1.1 201 Created
X-Request-Id: 7b5a7f79-ae7c-4040-b6cf-25cde58ad937
Location: https://health-api.gini.net/paymentRequests/b4bd3e80-7bd1-11e4-95ab-000000000000
Content-Type: application/vnd.gini.v1+json
Request
Key Mandatory Description
sourceDocumentLocation no the URI of the source document whenever the payment details were extracted by the Gini system beforehand
paymentProvider no the id of the target payment provider - see payment providers
recipient no the recipient of the payment
iban yes the iban (international bank account number) of the payment recipient
bic no the bic (bank identifier code) for the payment
amount yes the amount of the payment see (amount)
purpose yes the purpose of the payment, e.g. the invoice or the customer identifier

Getting a Payment Request

Payment Requests can be retrieved from both Pay API(using header application/vnd.gini.v1+json) and Health API (using application/vnd.gini.v3+json)

get a payment request from Health API

GET /paymentRequests/b4bd3e80-7bd1-11e4-95ab-000000000000
Host: health-api.gini.net
Authorization: BEARER c796535e-32e4-11eb-b966-e30e07dee3dc
Accept: application/vnd.gini.v3+json

response

{
  "createdAt": "2020-12-07T15:50:23",
  "recipient": "Dr. med. Hackler",
  "iban": "DE02300209000106531065",
  "requesterUri": "ginipay-example://payment-requester?paymentRequestId=b4bd3e80-7bd1-11e4-95ab-000000000000",
  "bic": "CMCIDEDDXXX",
  "amount": "335.50:EUR",
  "purpose": "ReNr AZ356789Z",
  "status": "paid",
  "_links": {
     "paymentProvider": "https://health-api.gini.net/paymentProviders/7e72441c-32f8-11eb-b611-c3190574373c",
     "_self": "https://health-api.gini.net/paymentRequests/b4bd3e80-7bd1-11e4-95ab-000000000000"
  }
}

get a payment request from Pay API

GET /paymentRequests/b4bd3e80-7bd1-11e4-95ab-000000000000
Host: pay-api.gini.net
Authorization: BEARER c796535e-32e4-11eb-b966-e30e07dee3dc
Accept: application/vnd.gini.v1+json

response

{
  "createdAt": "2020-12-07T15:50:23",
  "recipient": "Dr. med. Hackler",
  "iban": "DE02300209000106531065",
  "requesterUri": "ginipay-example://payment-requester?paymentRequestId=b4bd3e80-7bd1-11e4-95ab-000000000000",
  "bic": "CMCIDEDDXXX",
  "amount": "335.50:EUR",
  "purpose": "ReNr AZ356789Z",
  "status": "paid",
  "_links": {
     "payment": "https://pay-api.gini.net/paymentRequests/b4bd3e80-7bd1-11e4-95ab-000000000000/payment",
     "sourceDocumentLocation": "https://pay-api.gini.net/documents/88090c5a-32ed-11eb-9e1a-9f2bc4656a7d",
     "_self": "https://pay-api.gini.net/paymentRequests/b4bd3e80-7bd1-11e4-95ab-000000000000"
  }
}
Response
Key Description
createdAt ISO 8601 date string defining point in time when the payment request was created
recipient the recipient of the payment
iban the iban (international bank account number) of the payment recipient
bic the bic (bank identifier code) for the payment
amount the amount of the payment see (amount).
purpose the purpose of the payment, e.g. the invoice or customer identifier
status status depending on the comparison of the payment request with the actual payment can be "open", "paid" or "invalid"
requesterUri the uri of the business SDK app for returning after successful payment. Contains the payment request id as parameter
createdAt ISO 8601 timestamp in UTC timezone, defines the point in time when the payment request was created
_links object with links to other resources like document and payment

Resolving a Payment Request

A payment is sent by a payment provider in order to resolve a payment request after it was paid. The response contains the resolved payment request.

post the payment

POST /paymentRequests/b4bd3e80-7bd1-11e4-95ab-000000000000/payment
Host: pay-api.gini.net
Authorization: BEARER c796535e-32e4-11eb-b966-e30e07dee3dc
Content-Type: application/vnd.gini.v1+json

with

{
  "recipient": "Dr. med. Hackler",
  "iban": "DE02300209000106531065",
  "bic": "CMCIDEDDXXX",
  "amount": "335.50:EUR",
  "purpose": "ReNr AZ356789Z"
}

response

HTTP/1.1 201 Created
X-Request-Id: 7b5a7f79-ae7c-4040-b6cf-25cde58ad937
Content-Type: application/vnd.gini.v1+json

{
  "createdAt": "2020-12-07T15:50:23",
  "recipient": "Dr. med. Hackler",
  "iban": "DE02300209000106531065",
  "requesterUri": "ginipay-example://payment-requester?paymentRequestId=b4bd3e80-7bd1-11e4-95ab-000000000000",
  "bic": "CMCIDEDDXXX",
  "amount": "335.50:EUR",
  "purpose": "ReNr AZ356789Z",
  "status": "paid",
  "_links": {
     "payment": "https://pay-api.gini.net/paymentRequests/b4bd3e80-7bd1-11e4-95ab-000000000000/payment",
     "sourceDocumentLocation": "https://pay-api.gini.net/documents/88090c5a-32ed-11eb-9e1a-9f2bc4656a7d",
     "_self": "https://pay-api.gini.net/paymentRequests/b4bd3e80-7bd1-11e4-95ab-000000000000"
  }
}
Request Body
Key Mandatory Description
recipient no the recipient of the payment
iban yes the iban (international bank account number) of the payment recipient
bic no the bic (bank identifier code) for the payment
amount yes the amount of the payment see (amount)
purpose yes the purpose of the payment, e.g. the invoice or customer identifier

Response

See getting a payment request

Getting a Payment

get the payment

GET /paymentRequests/b4bd3e80-7bd1-11e4-95ab-000000000000/payment
Host: pay-api.gini.net
Authorization: BEARER c796535e-32e4-11eb-b966-e30e07dee3dc
Accept: application/vnd.gini.v1+json

response

{
  "paidAt": "2020-12-07T15:53:26",
  "recipient": "Dr. med. Hackler",
  "iban": "DE02300209000106531065",
  "bic": "CMCIDEDDXXX",
  "amount": "335.50:EUR",
  "purpose": "ReNr AZ356789Z",
  "_links": {
     "paymentRequest": "https://pay-api.gini.net/paymentRequests/b4bd3e80-7bd1-11e4-95ab-000000000000",
     "sourceDocumentLoction": "https://pay-api.gini.net/documents/88090c5a-32ed-11eb-9e1a-9f2bc4656a7d",
     "self": "https://pay-api.gini.net/payment/b4bd3e80-7bd1-11e4-95ab-000000000000/payment"
  }
}
Response
Key Description
paidAt ISO 8601 date string defining point in time when the payment request was resolved
recipient the recipient of the payment
iban the iban (international bank account number) of the payment recipient
bic the bic (bank identifier code) for the payment
amount the amount of the payment see (amount).
purpose the purpose of the payment, e.g. the invoice or customer identifier
_links object with links to other resources e.g. document and paymentRequest

Managing Anonymous Gini Accounts

In order to achieve best results, the Gini Pay API must be able to track the requests down to individual users for the following reasons:

Gini offers various ways to perform requests on behalf of the individual users without requiring physical interaction. Depending on your use case and your product's architecture, the following API authentication methods are available:

Communicating with the Gini Pay API via Backend / Gateway

request the list of user1's documents

curl -v -H 'Accept: application/vnd.gini.v1+json'
    -u 'client-id:client-secret'
    -H 'X-User-Identifier: user1'
    https://pay-api.gini.net/documents

This authentication scheme is based on HTTP Basic Authentication. Your application needs to use HTTP Basic Authentication to authenticate itself with the Gini Pay API. Additionally, another header called X-User-Identifier is sent together with the Authorization header in one request. This header is used by the API to identify individual users. Your application is free to choose whatever value it wants for the header, as long as the following constraints are met:

authenticating on behalf of a derived user

The access token is only needed if it is created by a trusted system (eg. backend or gateway) and used by a untrusted device (eg. smartphone).

curl -v -X POST -H 'X-User-Identifier: user1'
    -H 'Accept: application/vnd.gini.v1+json'
    -u 'client-id:secret' 'https://pay-api.gini.net/login'
POST https://pay-api.gini.net/login
Authorization: Basic Y2xpZW50LWlkOnNlY3JldA==
Host: pay-api.gini.net
accept: application/vnd.gini.v1+json

example response

{
  "access_token":"6c470ffa-abf1-41aa-b866-cd3be0ee84f4",
  "token_type":"bearer",
  "expires_in":3599
}

The returned access token can now be used to make requests to the Gini Pay API on behalf of the user. To do so, send the access token as a bearer token in the Authorization request header:

GET /documents HTTP/1.1
Host: pay-api.gini.net
Authorization: BEARER 6c470ffa-abf1-41aa-b866-cd3be0ee84f4
Accept: application/vnd.gini.v1+json
Connection: close

Direct Communication between Client Devices and the Gini Pay API

Gini offers the User Center API (UC API) to work with the Gini users. Here is a quick step-by-step guide that outlines how to create and use a new anonymous Gini account. Each step links to the corresponding section in the UC API where you can read more details about it.

  1. obtain the client token
  2. create a new user
  3. log in as a new user
  4. make API requests with the access token

Authenticate the Client

obtain the client token

curl -v -H 'Accept: application/json'
    -u 'client-id:client-secret'
    'https://user.gini.net/oauth/token?grant_type=client_credentials'

the successful response will have HTTP status 200 and the client access token 1eb7ca49-d99f-40cb-b86d-8dd689ca2345 will be returned

{
  "access_token":"1eb7ca49-d99f-40cb-b86d-8dd689ca2345",
  "token_type":"bearer","expires_in":43199,"scope":"read"
}

Before you are able to use the UC API, you need to obtain a client access token. The client access token authorizes your client (i.e. your application) against the UC API and allows you to create a new user.

At this point it is assumed that you already have the client ID client-id and the client secret client-secret. These will authorize your client (with HTTP Basic Authentication) to obtain the client access token, see the example on the right.

For more details see the corresponding UC API section.

Create a New User

create a new user

curl -v -X POST --data '{"email":"random@example.org", "password":"geheim"}'
    -H 'Content-Type: application/json'
    -H 'Accept: application/json'
    -H 'Authorization: BEARER 1eb7ca49-d99f-40cb-b86d-8dd689ca2345'
    'https://user.gini.net/api/users'

the above command creates a new user random@example.org with password geheim. If the creation was successful, the HTTP response has status 201 and contains the Location header pointing to the new user. Your client is now allowed to create a new user authorized by the client access token.

Once the client access token is successfully obtained, it's time to create a new user. To do so we require two more values: a username and a password. The username must be represented by a correct email address whose domain part is easily linkable to your application. For example, if your company is called Example Inc. then app.example.org would be a good domain name to use for your application's user accounts.

For more details see the corresponding UC API section.

Authenticate on behalf of a New User

login as a new user

curl -v -X POST --data-urlencode 'username=random@example.org'
    --data-urlencode 'password=geheim'
    -H 'Content-Type: application/x-www-form-urlencoded'
    -H 'Accept: application/json' -u 'client-id:client-secret'
    'https://user.gini.net/oauth/token?grant_type=password'

After the new user is created, you can log in. Note that log in request uses HTTP Basic Authentication with the client ID as a username and with the client secret as a password. It does not require a client access token. The request response will contain an access token that can be used to make API requests on behalf of the new user.

For more details see the corresponding UC API section.

Make API Requests with the Access Token

use the access token you obtained to make API requests

GET /documents HTTP/1.1
Host: pay-api.gini.net
Authorization: BEARER 760822cb-2dec-4275-8da8-fa8f5680e8d4
Accept: application/vnd.gini.v1+json
Connection: close

In order to make API requests, send the access token as a bearer token in the Authorization request header.

User Center API

Gini's User Center offers an API to programmatically create new Gini accounts and to make API requests on behalf of the created user.

Client Authentication

All access to the User Center API requires client authentication. A client can authenticate itself with the Client Credentials Grant described in RFC 6749. In short, the client exchanges its client ID and client secret for an access token.

Request

get a client access token

curl -v -H 'Accept: application/json'
    -u 'client-id:secret'
    'https://user.gini.net/oauth/token?grant_type=client_credentials'
GET /oauth/token?grant_type=client_credentials HTTP/1.1
Authorization: Basic Y2xpZW50LWlkOnNlY3JldA==
Host: user.gini.net
Accept: application/json

example response

{
  "access_token":"74c1e7fe-e464-451f-a6eb-8f0998c46ff6","token_type":"bearer","expires_in":3599
}

In order to get a client access token, send a GET request to /oauth/token?grant_type=client_credentials. The request must contain a basic HTTP access authorization header with the client ID as a username and the client secret as a password.

The client can now use the returned access token to make requests to the User Center API by sending the token as a bearer token in the Authorization request header:

GET /api/users/c1e60c6b-a0a4-4d80-81eb-c1c6de729a0e HTTP/1.1
Host: user.gini.net
Authorization: BEARER 74c1e7fe-e464-451f-a6eb-8f0998c46ff6
Accept: application/json

Authenticating on behalf of a User

authenticating on behalf of a user

curl -v -X POST --data-urlencode
    'username=some_user@example.com'
    --data-urlencode 'password=supersecret'
    -H 'Content-Type: application/x-www-form-urlencoded'
    -H 'Accept: application/json'
    -u 'client-id:secret' 'https://user.gini.net/oauth/token?grant_type=password'
POST /oauth/token?grant_type=password HTTP/1.1
Authorization: Basic Y2xpZW50LWlkOnNlY3JldA==
Host: user.gini.net
Accept: application/json
Content-Type: application/x-www-form-urlencoded

username=some_user@example.com&password=supersecret

example response

{
  "access_token":"6c470ffa-abf1-41aa-b866-cd3be0ee84f4",
  "token_type":"bearer",
  "expires_in":3599
}

The returned access token can now be used to make requests to the Gini Pay API on behalf of the user. To do so, send the access token as a bearer token in the Authorization request header:

GET /documents HTTP/1.1
Host: pay-api.gini.net
Authorization: BEARER 6c470ffa-abf1-41aa-b866-cd3be0ee84f4
Accept: application/vnd.gini.v1+json
Connection: close

The Resource Owner Password Credentials Grant can be used to exchange a user's email address and a password with an access token. The access token can then be used to make requests to the Gini API on behalf of the user.

Request
Key Description
username The user's email address.
password The user's password.

Note that the client must authenticate itself using basic HTTP access authentication with its ID as a username and its secret as a password.

Creating a New User

creating a new user

curl -v -X POST --data '{"email":"some_user@example.com", "password":"supersecret"}'
    -H 'Content-Type: application/json'
    -H 'Accept: application/json'
    -H 'Authorization: BEARER 74c1e7fe-e464-451f-a6eb-8f0998c46ff6'
    'https://user.gini.net/api/users'
POST /api/users HTTP/1.1
Host: user.gini.net
Authorization: BEARER 74c1e7fe-e464-451f-a6eb-8f0998c46ff6
Content-Type: application/json

{"email":"some_user@example.com","password:"supersecret"}

example response

HTTP/1.1 201 Created
Location: https://user.gini.net/api/users/c1e60c6b-a0a4-4d80-81eb-c1c6de729a0e
Content-Length: 0

In order to create a new user, submit a POST request to /api/users.

Request
Key Description
email The new user's email address (will be used as login username).
password The new user's password (must be at least 6 characters long).

If the request entity was invalid (missing field(s), password < 6 characters etc.) or a user with that email address already exists, the API will respond with 400 Bad Request.

Retrieving User Information

retrieving user information

GET /api/users/88a28076-18e8-4275-b39c-eaacc240d406 HTTP/1.1
Host: user.gini.net
Authorization: BEARER 74c1e7fe-e464-451f-a6eb-8f0998c46ff6
Accept: application/json

Response

{
  "id":"88a28076-18e8-4275-b39c-eaacc240d406",
  "email":"some_user@example.com"
}

Information about a user can be retrieved with a GET request to /api/users/{userId}

Response
Key Description
id Unique User ID.
email The user's email address.

Changing a User's Password and/or Email

change a user's password and/or email

PUT /api/users/c1e60c6b-a0a4-4d80-81eb-c1c6de729a0e HTTP/1.1
Host: user.gini.net
Authorization: BEARER 74c1e7fe-e464-451f-a6eb-8f0998c46ff6
Content-Type: application/json

with

{"oldPassword":"supersecret","password:"anothersecret"}

or

{"oldEmail":"old@email.com","email:"my.new@email.com"}

or

{
 "oldPassword":"supersecret",
 "password":"anothersecret",
 "oldEmail":"old@email.com",
 "email":"my.new@email.com"}

A user's password and/or email can be changed with a PUT request to /api/users/{userId}. In order to update a user's password and/or email, the current password/email must be provided.

Request
Key Description
oldPassword the user's current password
password the password to which the user's password should be changed to
oldEmail the user's current email
email the email to which the user's email should be changed to

Deleting a User

delete a user

DELETE /api/users/16aecc72-8032-4df6-9686-eaf4ec9532b8 HTTP/1.1
Host: user.gini.net
Authorization: BEARER 74c1e7fe-e464-451f-a6eb-8f0998c46ff6
Content-Type: application/json

An existing user can be deleted with a DELETE request to /api/users/{userId}. This also deletes all data associated with that user (e.g. access tokens, documents and extractions).

Overview of User Authentication Flows

As mentioned above, Gini Pay API supports different authentication flows, depending on the use case. API differentiates between anonymous and derived users. Client credentials you received when you registered your application support either derived or anonymous user flows. Make sure to follow our security guidelines on how to secure your data.

There are currently 4 different authentication flows possible with our API:

  1. Communication from a trusted device using a derived user
  2. Communication from an untrusted device using a derived user
  3. Communication from both trusted and untrusted devices using a derived user (mix of Option 1 and Option 2)
  4. Communication from an untrusted device using an anonymous user

Communication from a trusted device using a derived user

Communicate with Gini Pay API using client credentials (basic authentication) from a trusted device e.g. your trusted backend. Derived user is automatically created if it doesn't exist already.

curl -v -H 'Accept: application/vnd.gini.v1+json'
    -u 'client-id:client-secret'
    -H 'X-User-Identifier: user_hash_123'
    https://pay-api.gini.net/documents

example response

{
  "documents": [
    {...},
    {...},
    ...
  ]
}

image info

Communication from an untrusted device using a derived user

To communicate with Gini Pay API from untrusted devices, you need to acquire a token from Gini Pay API for the user and hand it over to the untrusted device. User is derived/created from X-User-Identifier header. The value is up to you, usually a stable hash of your internal user identifier

Acquire a token and hand it over to the untrusted device

curl -v -X POST
        -H 'X-User-Identifier: user_hash_123'
        -H 'Accept: application/vnd.gini.v1+json'
        -u 'client-id:secret' 'https://pay-api.gini.net/login'

example response

{
  "access_Token": "S+YXT+XneST13aqoBRBgBiw6Quk=",
  "token_type": "bearer",
  "expires_in": 43199
}

Query API with the acquired token

curl -X GET -i https://pay-api.gini.net/documents
     -H 'Authorization: BEARER S+YXT+XneST13aqoBRBgBiw6Quk='
     -H 'Accept: application/vnd.gini.v1+json'

image info

Communication from both trusted and untrusted devices using a derived user

When your communicate with our API from a trusted device using client credentials (option 1), derived user is automatically created for a given X-User-Identifier when it's specified for the first time. From then on, derived user stays fixed for this client id and X-User-Identifier. You can also acquire an access token for this user so it can be used by an untrusted device. This scenario is valid when you have both trusted and untrusted devices communicate with our API and you don't want client credentials stored on an untrusted device.

Derived user is automatically created for user_hash_789 first time client uses it from a trusted device

curl -v -H 'Accept: application/vnd.gini.v1+json'
    -u 'client-id:client-secret'
    -H 'X-User-Identifier: user_hash_789'
    https://pay-api.gini.net/documents

Trusted device can now acquire the token for an already existing user_hash_789

curl -v -X POST
        -H 'X-User-Identifier: user_hash_789'
        -H 'Accept: application/vnd.gini.v1+json'
        -u 'client-id:secret' 'https://pay-api.gini.net/login'

example response

{
  "access_Token": "G+YXT+XneST13aqoBRBgBiw6Qza=",
  "token_type": "bearer",
  "expires_in": 43199
}

Hand the acquired access token over to an untrusted device so that it can query API

curl -X GET -i https://pay-api.gini.net/documents
     -H 'Authorization: BEARER G+YXT+XneST13aqoBRBgBiw6Qza='
     -H 'Accept: application/vnd.gini.v1+json'

image info

Communication from an untrusted device using an anonymous user

This is the only flow that requires a communication with two APIs: Pay API and User Center API. This flow is done in 4 steps:

  1. Obtain the client token using client credentials
  2. Create a new user using the client token
  3. Log in on behalf of the user and acquire an access token
  4. Make API requests with the access token

Step 1. Get client token from a trusted device

curl -v -H 'Accept: application/json'
    -u 'client-id:client-secret'
    'https://user.gini.net/oauth/token?grant_type=client_credentials'

example response

{
  "access_token":"6c470ffa-abf1-41aa-b866-cd3be0ee84f4",
  "token_type":"bearer",
  "expires_in":3599
}

Step 2. Use the client token above to create user with arbitrary username and password (user usually identifies the physical device e.g mobile phone)

curl -v -X POST --data '{"email":"random@example.org", "password":"geheim"}'
    -H 'Content-Type: application/json'
    -H 'Accept: application/json'
    -H 'Authorization: BEARER 6c470ffa-abf1-41aa-b866-cd3be0ee84f4'
    'https://user.gini.net/api/users'

example response

HTTP/1.1 201 Created
Location: https://user.gini.net/api/users/6407244f-9edf-4119-8641-be18c39226d8
Content-Length: 0

Step 3. Authenticate on behalf of the user using client credentials and acquire the access token

curl -v -X POST --data-urlencode 'username=random@example.org'
    --data-urlencode 'password=geheim'
    -H 'Content-Type: application/x-www-form-urlencoded'
    -H 'Accept: application/json' -u 'client-id:client-secret'
    'https://user.gini.net/oauth/token?grant_type=password'

example response

{
  "access_token":"6c470ffa-abf1-41aa-b866-cd3be0ee84f4",
  "token_type":"bearer",
  "expires_in":3599
}

Step 4. Communicate with the API from an untrusted device with the acquired access token

curl -X GET -i https://pay-api.gini.net/documents
     -H 'Authorization: BEARER 6c470ffa-abf1-41aa-b866-cd3be0ee84f4'
     -H 'Accept: application/vnd.gini.v1+json'

Access tokens expire. So last two steps need to be repeated to refresh the token and hand it over to the untrusted device for use.

image info

Securing your data

Using a single user for all your uploads is against our security standards. Multi-user authentication provides several benefits that can help protect your customers' documents and sensitive information. Here are two important reasons to opt for multi-user authentication:

  1. Mitigate the risk of putting all customers' documents under one credential: With a single-user implementation, all customers' documents are stored under one credential. This creates a significant risk if the token or identifier associated with that credential is leaked or stolen. In such cases, an attacker can gain access to all the documents of all users, compromising their confidentiality and potentially causing significant harm to your customers and your business. By implementing multi-user authentication, you can avoid this risk by using separate credentials for each user. This ensures that if one user's credential is compromised, the other users' documents remain protected.

  2. Protect against compromised credentials: Even if your credentials are secure today, there is always a risk that they could be compromised in the future. If this happens, a hacker could easily gain access to all your customers' documents. With multi-user authentication, however, each user has their own unique credentials. This means that if one user's credentials are compromised, the other users' documents remain protected.

Overall, multi-user authentication is an essential tool for protecting your customers' documents and sensitive information. By using separate credentials for each user, you can minimize the risks associated with single-user authentication and protect against compromised credentials.

Troubleshooting

If you have trouble using the Gini Pay API and you need to contact the support, there is some information you should always provide in order for us to help you quickly and efficiently.

X-Request-Id

The request id is generated for every request against the Gini Pay API and tracked through the whole system. It is included in every response you receive from the Gini Pay API as the HTTP header X-Request-Id. Please refer to it when you contact our support.

Document Id

The document id is generated for every accepted upload. It is included in the Location HTTP header which is part of the response to a successful upload. Please refer to the document id if you have questions related to the specific document upload.