# Integration API Specification

The service exposes an HTTP Restful API with the following endpoints.

# Internal API

The group of calls below is intended for the admin running the service itself.

Superadmin related


# Create an integrator account

Example

# Request

curl -X POST -H "Authorization: Bearer <superadmin-key>" https://server/v1/admin/accounts

# Request body

{
	"cspUrlPrefix": "my-csp-url-prefix",
	"cspPubKey": "hexBytes",
	"name": "My integrator account",
    "email": "admin@account.net"
}

# HTTP 200

{
	"id": "1234567890",
	"apiKey": "ksjdhfksjdh..."   // The integrator (secret) key to use the API
}

# HTTP 400

{
    "error": "Message goes here"
}

# Update an integrator account

Example

# Request

curl -X PUT -H "Authorization: Bearer <superadmin-key>" https://server/v1/admin/accounts/<id>

# Request body

{
	"cspUrlPrefix": "my-csp-url-prefix",
	"cspPubKey": "hexBytes",
	"name": "My integrator account",
}

# HTTP 200

{
    "id": "1234567890"
}

# HTTP 400

{
    "error": "Message goes here"
}

# Reset an integrator API key

Example

# Request

curl -X PATCH -H "Authorization: Bearer <superadmin-key>" https://server/v1/admin/accounts/<id>/key

# HTTP 200

{
    "id": "1234567890",
    "apiKey": "priv_abcdefghijklmnoprstuvwxyz"
}

# HTTP 400

{
    "error": "Message goes here"
}

# Get an integrator account

Example

# Request

curl -H "Authorization: Bearer <superadmin-key>" https://server/v1/admin/accounts/<id>

# HTTP 200

{
	"cspUrlPrefix": "my-csp-url-prefix",
	"cspPubKey": "hexBytes",
	"name": "My integrator account",
}

# HTTP 400

{
    "error": "Message goes here"
}

# Delete an integrator account

Example

# Request

curl -X DELETE -H "Authorization: Bearer <superadmin-key>" https://server/v1/admin/accounts/<id>

# HTTP 200

// empty response

# HTTP 400

{
    "error": "Message goes here"
}

# Integrator API (Private)

Integrator related


The following endpoints are authenticated by using the integrator secret key. They allow integrators to manage the organizations related to their customers.

# Create an organization

Example This request submits a transaction to the [voting blockchain](../architecture/services/vochain.md) which can take some time (~15 seconds) to be accepted and mined. Therefore, the return values of this method should not be considered valid until the Transaction Status method is called, using the `txHash` value to confirm that the desired transaction has been mined. Only then is it safe to query for the organization you have created.

# Request

curl -X POST -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/account/organizations

# Request body

{
    "name": "Organization name",
    "description": "my-description",
    "header": "https://my/header.jpeg",
    "avatar": "https://my/avatar.png"
}

# HTTP 200

{
    "organizationId": "0x1234...",
    "apiToken": "pub_qwertyui...",   // API token for public voting endpoints
    "txHash": "0x1234...",
}

# HTTP 400

{
    "error": "Message goes here"
}

# Get an organization

Example

# Request

curl -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/account/organizations/<organizationId>

# HTTP 200

{
    "apiToken": "qoiuwhgoiauhsdaiouh",   // the public API token
    "name": "Organization name",
    "description": "",
    "header": "https://my/header.jpeg",
    "avatar": "https://my/avatar.png"
}

# HTTP 400

{
    "error": "Message goes here"
}

# Get an organization list

Retrieves the full list of organizations created by the given integrator key

Example

# Request

curl -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/account/organizations

# HTTP 200

{
    "organizations":
        [
            {
                "api_token":"qoiuwhgoiauhsdaiouh",
                "name":"Organization name",
                "description":"",
                "header": "https://my/header.jpeg",
                "avatar": "https://my/avatar.png"
            },
            ...
        ]
}

# HTTP 400

{
    "error": "Message goes here"
}

# Remove an organization

Example

# Request

curl -X DELETE -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/account/organizations/<organizationId>

# HTTP 200

// empty response

# HTTP 400

{
    "error": "Message goes here"
}

# Reset the public API token of an organization

Example

# Request

curl -X PATCH -H "Authorization: Bearer <integrator-key>" https://server/v1/account/organizations/<id>/key

# HTTP 200

{
    "apiToken": "zxcvbnm"
}

# HTTP 400

{
    "error": "Message goes here"
}

Organization related


These methods are also intended for integrators, but they are expected to do the duties of an organization managing a proposal.

# Set Organization metadata

Example This request submits a transaction to the [voting blockchain](../architecture/services/vochain.md) which can take some time (~15 seconds) to be accepted and mined. Therefore, the return values of this method should not be considered valid until the Transaction Status method is called, using the `txHash` value to confirm that the desired transaction has been mined. Only then is it safe to query for the organization you have updated.

# Request

curl -X PUT -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/organizations/<organizationId>/metadata

# Request body

{
    "name": "Organization name",
    "description": "my-description",
    "header": "https://my/header.jpeg",
    "avatar": "https://my/avatar.png"
}

# HTTP 200

{
    "organizationId": "0x1234...",
    "contentUri": "ipfs://1234...",
    "txHash": "0x1234...",
}

# HTTP 400

{
    "error": "Message goes here"
}

# Check a transaction status

Example

# Request

curl -X GET -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/transactions/<transaction-hash>

# HTTP 200

{
    "mined": true // true | false
}

# HTTP 400

{
    "error": "Message goes here"
}

# Create an election

Generates a Merkle Tree with the given current census keys and generates a voting process with the given metadata.

Example This request submits a transaction to the voting blockchain which can take some time (~15 seconds) to be accepted and mined. Therefore, the return values of this method should not be considered valid until the Transaction Status method is called, using the txHash value to confirm that the desired transaction has been mined. Only then is it safe to query for the election you have created.

# Request

curl -X POST -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/organizations/<organizationId>/elections/signed
curl -X POST -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/organizations/<organizationId>/elections/blind

# Request body

{
    "title": "Important election",
    "description": "Description here",
    "header": "https://my/header.jpeg",
    "streamUri": "https://youtu.be/1234",
    "startDate": "2021-10-25T11:20:53.769Z", // can be empty
    "endDate": "2021-10-30T12:00:00.000Z",
    "questions": [
        {
            "title": "Question 1",
            "description": "(optional)",
            "choices": ["Yes", "No", "Maybe"]  // simplified version of title/value
        }, {...}
    ],
    "confidential": false,  // Metadata access restricted to only census members
    "hiddenResults": true, // Encrypt results until the election ends
    "census": "<censusId>" // Optional for CSP processes
}

# HTTP 200

{
    "electionId": "0x1234...",
    "txHash": "0x1234...",
}

# HTTP 400

{
    "error": "Message goes here"
}

# Set an election status

Generates a Merkle Tree with the given current census keys and generates a voting process with the given metadata.

Example This request submits a transaction to the voting blockchain which can take some time (~15 seconds) to be accepted and mined. Therefore, the desired results of this method should not be considered valid until the Transaction Status method is called, using the txHash value to confirm that the desired transaction has been mined. Only then is it safe to query for the election you have updated.

# Request

curl -X PUT -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/elections/<electionId>/status

# Request body

{
    "status": "READY" // READY, ENDED, CANCELED, PAUSED
}

# HTTP 200

{
    "txHash": "0x1234..."
}

# HTTP 400

{
    "error": "Message goes here"
}

# List elections (filtered)

Allows unrestricted listing, paging and filtering for the integrator backend to display all info to organization admins.

Example

# Request

curl -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/organizations/<organizationId>/elections

curl -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/organizations/<organizationId>/elections/upcoming
curl -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/organizations/<organizationId>/elections/active
curl -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/organizations/<organizationId>/elections/paused
curl -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/organizations/<organizationId>/elections/canceled
curl -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/organizations/<organizationId>/elections/ended

curl -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/organizations/<organizationId>/elections/blind
curl -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/organizations/<organizationId>/elections/signed

# HTTP 200

[
    {
        "title": "Important election",
        "description": "",
        "header": "https://my/header.jpeg",
        "status": "UPCOMING", // "UNKNOWN" | "PAUSED" | "CANCELED" | "UPCOMING" | "ACTIVE" | "ENDED"
        "startDate": "2021-10-25T11:20:53.769Z", // can be empty
        "endDate": "2021-10-30T12:00:00.000Z",
        "proofType": "blind", // "blind | "ecdsa"
    }, {...}
]

# HTTP 400

{
    "error": "Message goes here"
}

# Get an election

Allows unrestricted access for the integrator backend to display all info to organization admins. Confidential elections do not require any additional step, just the integrator API key.

Example

# Request

curl -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/elections/<electionId>

# Request body

{
  "chainId": "vocdoni-main-1",
  "type": "blind-confidential-hidden-results",
  "organizationId": "20323909c3e0965d1489893db1512b32b55707ea",
  "title": "test election",
  "description": "description test 1",
  "header": "https://source.unsplash.com/random/800x600",
  "questions": [
    {
      "title": "test q1",
      "description": "",
      "choices": [
        {
          "title": "Yes",
          "value": 0,
        },
        {
          "title": "No",
          "value": 1,
        },
      ],
    },
    {
      "title": "test q2",
      "description": "",
      "choices": [
        {
          "title": "Yes",
          "value": 0,
        },
        {
          "title": "No",
          "value": 1,
        },
      ],
    },
    {
      "title": "test q3",
      "description": "",
      "choices": [
        {
          "title": "Yes",
          "value": 0,
        },
        {
          "title": "No",
          "value": 1,
        },
      ],
    }
  ],
  "status": "ENDED", // "UNKNOWN" | "PAUSED" | "CANCELED" | "UPCOMING" | "ACTIVE" | "ENDED"
  "proofType": "blind", // "blind" | "ecdsa"
  "streamUri": "uri",
  "voteCount": 1,
  "results": [
    {
      "title": [
        "Yes",
        "No"
      ],
      "value": [
        "1",
        "0"
      ]
    },
    {
      "title": [
        "Yes",
        "No"
      ],
      "value": [
        "1",
        "0"
      ]
    },
    {
      "title": [
        "Yes",
        "No"
      ],
      "value": [
        "1",
        "0"
      ]
    }
  ],
  "organizationId": "20323909c3e0965d1489893db1512b32b55707ea",
  "electionId": "47f2c1f1164a27db4f5e7b825f8ec064c44da88a83ff72b90e5755fff8bfb53b",
  "aggregation": "discrete-counting",
  "display": "multiple-question"
}

# HTTP 200

{
    "electionId": "0x1234..."
}

# HTTP 400

{
    "error": "Message goes here"
}

# Create a census

A census where public keys or token slots (that will eventually contain a public key) are stored. A census can start with 0 items, and public keys can be imported later on.

If census tokens are allocated, users will need to generate a wallet on the frontend and register the public key by themselves. This prevents both the API and the integrator from gaining access to the private key.

Example

# Request

curl -X POST -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/censuses

# Request body

{
    "name": "2021 members"
}

# HTTP 200

{
    "censusId": "123456789..."
}

# HTTP 400

{
    "error": "Message goes here"
}

# Add N census tokens (once)

Creates N census tokens for voters to register their public key in the future.

Example

# Request

curl -X POST -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/censuses/<censusId>/tokens/flat

# Request body

{
    "size": 450
}

# HTTP 200

{
    "censusId": "123456789...",
    "size": 700,  // new size
    "tokens": [
        "jashdlkfjahs", "uyroeituwyert", "e7rg9e87rn9", ... // x 450
    ]
}

# HTTP 400

{
    "error": "Message goes here"
}

# Add weighted census tokens (once)

Creates weighted census tokens so that voters with the token can register their public key to the appropriate census weight.

Example

# Request

curl -X POST -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/censuses/<censusId>/tokens/weighted

# Request body

{
    "weights": [
        40, 70, 200
    ]
}

# HTTP 200

{
    "censusId": "123456789...",
    "size": 700,  // new size
    "tokens": [
        { "token": "jashdlkfjahs", "weight": 40 },
        { "token": "uyroeituwyert", "weight": 70 },
        { "token": "e7rg9e87rn9", "weight": 200 }
    ]
}

# HTTP 400

{
    "error": "Message goes here"
}

# Get census token (see a registered public key)

Allows integrators to check the status of a census token, given to a user.

If the token has already been redeemed, the public key will be used as part of the census normally.

Example

# Request

curl -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/censuses/<censusId>/tokens/<tokenId>

# HTTP 200

{
    "publicKey": "",   // no public key yet
    "weight": 20
}

# HTTP 400

{
    "error": "Message goes here"
}

# Remove a census token or public key from a census

Removes the given token or key from the given census. The next time it is used, the new key will be in effect.

Example

# Request

curl -X DELETE -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/censuses/<censusId>/tokens/<tokenId>
curl -X DELETE -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/censuses/<censusId>/keys/<publicKey>

# HTTP 200

// empty response

# HTTP 400

{
    "error": "Message goes here"
}

# Import public keys into a census

Import a group of public keys to an existing census. All voters have the same weight (1).

Example

# Request

curl -X POST -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/censuses/<censusId>/import/flat

# Request body

{
    "publicKeys": [
        "0x0312345678...",
        "0x0223456789...",
        ...
    ]
}

# HTTP 200

{
    "censusId": "123456789...",
    "size": 300
}

# HTTP 400

{
    "error": "Message goes here"
}

# Import weighted public keys into a census

Import a group of public keys to an existing census, using their respective weight.

Example

# Request

curl -X POST -H "Authorization: Bearer <integrator-key>" https://server/v1/priv/censuses/<censusId>/import/weighted

# Request body

{
    "entries": [
        { "publicKey": "0x0312345678...", "weight": 100 },
        { "publicKey": "0x02234567890...", "weight": 150 },
        ...
    ]
}

# HTTP 200

{
    "censusId": "123456789...",
    "size": 300
}

# HTTP 400

{
    "error": "Message goes here"
}

# Public API

(token API authenticated, voter apps call it directly)

# Get election list (per organization) – non-confidential

Example

# Request

curl -H "Authorization: Bearer <manager-key>" https://server/v1/pub/organizations/<organizationId>/elections

curl -H "Authorization: Bearer <manager-key>" https://server/v1/pub/organizations/<organizationId>/elections/upcoming
curl -H "Authorization: Bearer <manager-key>" https://server/v1/pub/organizations/<organizationId>/elections/active
curl -H "Authorization: Bearer <manager-key>" https://server/v1/pub/organizations/<organizationId>/elections/paused
curl -H "Authorization: Bearer <manager-key>" https://server/v1/pub/organizations/<organizationId>/elections/canceled
curl -H "Authorization: Bearer <manager-key>" https://server/v1/pub/organizations/<organizationId>/elections/ended

curl -H "Authorization: Bearer <manager-key>" https://server/v1/pub/organizations/<organizationId>/elections/blind
curl -H "Authorization: Bearer <manager-key>" https://server/v1/pub/organizations/<organizationId>/elections/signed

# HTTP 200

[
    {
        "id": "0x12345678...",
        "title": "Important election",
        "avatar": "https://my/avatar.png",
        "startDate": "2021-12-25T11:20:53.769Z",
        "endDate": "2021-10-30T12:00:00.000Z",
        "confidential": false,
        "hiddenResults": true,
        "proofType": "blind", // "blind | "ecdsa"
    }, {...}
]

# HTTP 400

{
    "error": "Message goes here"
}

# Get election info – non-confidential

Example

# Request

curl -H "Authorization: Bearer <organization-api-token>" https://server/v1/pub/elections/<electionId>

# HTTP 200

{
    "chainId": "vocdoni-main-1",
    "type": "signed-plain", // blind-plain, ...
    "title": "Important election",
    "description": "Description goes here",
    "header": "https://my/header.jpeg",
    "streamUri": "https://youtu.be/1234",
    "questions": [
        {
            "title": "Question 1",
            "description": "(optional)",
            "choices": [
                {
                    "title": "Yes",
                    "value": 0,
                },
                                {
                    "title": "No",
                    "value": 1,
                },
                                {
                    "title": "Maybe",
                    "value": 2,
                },
            ],
        }, {...}
    ],
    "status": "UPCOMING", // "UNKNOWN" | "PAUSED" | "CANCELED" | "UPCOMING" | "ACTIVE" | "ENDED"
    "voteCount": 1234,
    "proofType": "blind", // "blind" | "ecdsa"
    "results": [   // Empty array when no results []
        [ { "title": "Yes", "value": "1234" }, { "title": "No", "value": "2345" } ],
        [ { "title": "Yes", "value": "22" }, { "title": "No", "value": "33" } ]
    ]
}

# HTTP 400

{
    "error": "Message goes here"
}

# Get election info – confidential

Provides the details of a confidential voting process if the user holds a wallet that belongs to its census.

If {electionId} has been signed by the CSP, then it gets the Vochain parameters, decrypts the metadata and returns it to the caller.

URL Params:

Example

# Request

curl -H "Authorization: Bearer <organization-api-token>" https://server/v1/pub/elections/<election-id>/auth/<csp-shared-key>

# HTTP 200

{
    "chainId": "vocdoni-main-1",
    "type": "signed-plain", // blind-plain, ...
    "title": "Important election",
    "description": "Description goes here",
    "header": "https://my/header.jpeg",
    "streamUri": "https://youtu.be/1234",
    "questions": [
        {
            "title": "Question 1",
            "description": "(optional)",
            "choices": [
                {
                    "title": "Yes",
                    "value": 0,
                },
                                {
                    "title": "No",
                    "value": 1,
                },
                                {
                    "title": "Maybe",
                    "value": 2,
                },
            ],
        }, {...}
    ],
    "status": "UPCOMING", // "UNKNOWN" | "PAUSED" | "CANCELED" | "UPCOMING" | "ACTIVE" | "ENDED"
    "proofType": "blind", // "blind" | "ecdsa"
    "voteCount": 1234,
    "results": [   // Empty array when no results []
        [ { "title": "Yes", "value": "1234" }, { "title": "No", "value": "2345" } ],
        [ { "title": "Yes", "value": "22" }, { "title": "No", "value": "33" } ]
    ]
}

# HTTP 400

{
    "error": "Message goes here"
}

# Requesting a census proof

People voting on a signed process will need to package a vote envelope using the result of this call.

Note: This call does not apply to deployments where a custom CSP validation is being used.

Example

# Request

curl -H "Authorization: Bearer <organization-api-token>" https://server/v1/pub/elections/<electionId>/proof

# Request body

{
    "signature": "0x12345678..." // signing a well-known payload using the wallet
}

# HTTP 200

{
    "proof": "..."
}

# HTTP 400

{
    "error": "Message goes here"
}

# Submitting a vote (signed or blind)

Voters using the tiny JS SDK will get a base64 bundle including the vote and the census proof. This payload is submitted as a base64 string.

Example

# Request

curl -X POST -H "Authorization: Bearer <organization-api-token>" https://server/v1/pub/elections/<electionId>/vote

# Request body

{
    "vote": "<base64-signed-vote-transaction>" // see dvote-js
}

# HTTP 200

{
    "nullifier": "0x12345678..."
}

# HTTP 400

{
    "error": "Message goes here"
}

# Getting a ballot (nullifier)

Voters can check the status of their vote here, and eventually check the explorer link, for independent confirmation.

Example

# Request

curl -H "Authorization: Bearer <organization-api-token>" https://server/v1/pub/nullifiers/<nullifier>

# HTTP 200

{
    "electionId": "0x12345678...",
    "registered": true,
    "explorerUrl": "https://vaas.explorer.vote/nullifiers/0x12345678"
}

# HTTP 400

{
    "error": "Message goes here"
}

# Registering a voter's public key

This process needs to be done by the integrator's frontend, once.

As soon as a user runs an updated UI version, a new private key should be generated, and the public key should be registered, so that new votes can use this key.

If the wallet is lost, the integrator will need to remove the pubKey from the census and create a new census token when the new wallet is available.

Example

# Request

curl -X POST -H "Authorization: Bearer <organization-api-token>" https://server/v1/pub/censuses/<censusId>/token

# Request body

{
    "censusToken": "jashdlkfjahs",
    "publicKey": "0x03abcdef0123456789..."
}

# HTTP 200

// empty response

# HTTP 400

{
    "error": "Message goes here"
}

# Authentication API

Generic authentication


# Get a shared key to access the private data of an election

The CSP issues a per-process signature whenever the wallet belongs to the process's census. The signature can be used to retrieve confidential information, restricted to only census members.

The voter signs the electionID to prove that he/she has a private key within the election census. If everything is correct, the CSP returns sign({electionId}, cspPrivK).

  • election-id
  • signed-pid: sign({electionId}, voterPrivK)
Example

# Request

curl -H "Authorization: Bearer <organization-api-token>" https://server/v1/auth/elections/<election-id>/sharedkey

# Request body

{
	"authData": ["<signed-pid>"]
}

# HTTP 200

{
    "sharedkey": "0x1234567890abcde..."
}

# HTTP 400

{
    "error": "Message goes here"
}

# Get a token for requesting a plain/blind signature

The blind signature process involves a two step interaction.

In the first interaction, the voter proves to have a private key within the election census. If everything is correct, the backend replies with the tokenR, which the voter needs to use on the second step.

  • process-id
  • signed-pid: sign({electionId}, voterPrivK)
Example

# Request

curl -X POST -H "Authorization: Bearer <organization-api-token>" https://server/v1/auth/elections/<election-id>/ecdsa/auth
curl -X POST -H "Authorization: Bearer <organization-api-token>" https://server/v1/auth/elections/<election-id>/blind/auth

# Request body

{
	"authData": ["<signed-pid>"]
}

# HTTP 200

{
    "tokenR": "0x1234567890abcde..."
}

# HTTP 400

{
    "error": "Message goes here"
}

# Request the plain/blind signature for an ephemeral wallet

The user generates an ephemeral wallet and the received tokenR to generate a (plain or blinded) payload. This payload is sent to the backend, which will check the correctness and reply with a signature of the payload.

The voter then may unblind the response (if applicable) and use it as their vote signature.

Example

# Request

curl -X POST -H "Authorization: Bearer <organization-api-token>" https://server/v1/auth/elections/<electionId>/ecdsa/sign
curl -X POST -H "Authorization: Bearer <organization-api-token>" https://server/v1/auth/elections/<electionId>/blind/sign

# Request body

{
    "payload": "0xabcdef...",   // hash({electionId, address}) or blind(hash({electionId, address}))
    "tokenR": "0x1234567890abcde..."
}

# HTTP 200

{
    "signature": "0x1234567890abcde..."  // plain or blind signature
}

# HTTP 400

{
    "error": "Message goes here"
}

# Get the public keys that have requested a blind signature on an election

For transparency, external observers can request the exhaustive list of public keys that made a blind signature request.

Example

# Request

curl -H "Authorization: Bearer <organization-api-token>" https://server/v1/pub/elections/<electionId>/blind/authorized

# HTTP 200

{
    "publicKeys": [
        "0x12345678...",
        "0x23456789...",
        ...
    ]
}

# HTTP 400

{
    "error": "Message goes here"
}

Custom authentication API


# Get a shared key to access the private data of an election

This endpoint is conceptually the same as the one from above. The only difference lies on the custom logic that decides whether a voter is eligible or not.

The CSP issues a per-process signature whenever the wallet belongs to the process's census. The signature can be used to retrieve confidential information, restricted to only census members.

If the evidence provided is correct, the CSP returns sign({electionId}, cspPrivK).

  • election-id
  • signed-pid: sign({electionId}, voterPrivK)
Example

# Request

curl -X POST -H "Authorization: Bearer <organization-api-token>" https://server/v1/auth/elections/<election-id>/sharedkey

# Request body

{
    "authData": ["param1", "param2", ...]
}
#### HTTP 200
```json
{
    "sharedkey": "0x1234567890abcde..."
}

# HTTP 400

{
    "error": "Message goes here"
}

# Get a token for requesting a blind signature - custom

This endpoint is conceptually the same as the one from above. The only difference lies on the custom logic that decides whether a tokenR is generated or not.

The blind signature process involves a two step interaction.

In the first interaction, the voter proves their eligibility. If everything is correct, the backend replies with the tokenR, which the voter needs to use on the second step.

Example

# Request

curl -X POST -H "Authorization: Bearer <organization-api-token>" https://server/v1/auth/custom/elections/<electionId>/blind/auth

# Request body

{
    "authData": ["param1", "param2", ...]
}

# HTTP 200

{
    "tokenR": "0x1234567890abcde..."
}

# HTTP 400

{
    "error": "Message goes here"
}
Last Updated: 2/15/2022, 4:57:08 PM