Brief API voor het verzenden van {briefpost}

Versnel je briefverzending met de Pingen Brief API. Start direct met onze SDK’s en verstuur binnen no-time via PostNL, vanaf € 1,15 per brief.

API-documentatie openen
Pingen Letter API met PHP-codevoorbeeld en dashboardweergave

API voor print- en post automatisering

Onze APi is gratis

Wij geloven in de kracht van procesautomatisering. Daarom bieden we onze API gratis aan.

Meertalige SDK's

Met onze SDK's voor PHP, Python, GO en .Net wordt briefverzending in no-time geïntegreerd!

Volledig schaalbaar

Onze high-performance infrastructuur stelt je in staat om duizenden brieven per uur te verwerken.

Gemaakt voor developers

Een API met duidelijke documentatie, ontwikkeld door experts voor gemakkelijke integratie.

Track & Trace

Pingen biedt realtime updates en transparantie voor elke brief die via de API wordt verzonden.

Genereer inkomsten

Integrators kunnen nieuwe inkomsten genereren door postdienstverlening door te verkopen aan hun klanten.

Simpel starten, snel in gebruik.

De Pingen API is heel gebruiksvriendelijk, waardoor integratie eenvoudig verloopt. We bieden duidelijke documentatie en codevoorbeelden voor een snelle start.

API-documentatie openen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import pingen2sdk

pingen2sdk.client_id = "YOUR_OAUTH2_CLIENT_ID"
pingen2sdk.client_secret = "YOUR_OAUTH2_CLIENT_SECRET"

resp = pingen2sdk.OAuth.get_token(
   grant_type = "client_credentials",
   scope = "letter batch webhook organisation_read",
)

try:
   print(
        pingen2sdk.FileUpload(pingen2sdk.APIRequestor(resp["access_token"]))
        .request_file_upload()
        .data
   )
except pingen2sdk.error.PingenError as e:
   print(e.status_code)
   print(e.json_body)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

require __DIR__ . '/vendor/autoload.php';

$provider = new \Pingen\Provider\Pingen(
    array(
        'clientId' => 'YOUR_OAUTH2_CLIENT_ID',
        'clientSecret' => 'YOUR_OAUTH2_CLIENT_SECRET'
    )
);

$accessToken = $provider->getAccessToken('client_credentials');

$lettersEndpoint = (new \Pingen\Endpoints\LettersEndpoint($accessToken))
    ->setOrganisationId('YOUR_ORGANISATION_UUID');

$lettersEndpoint->uploadAndCreate(
    (new \Pingen\Endpoints\DataTransferObjects\Letter\LetterCreateAttributes())
        ->setFileOriginalName('your_filename.pdf')
        ->setAddressPosition('left')
        ->setAutoSend(false),
    fopen('path_to_file.pdf', 'r')
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import json
import requests

url_file_upload = 'https://api.pingen.com/file-upload'
url_letters = 'https://api.pingen.com/organisations/YOUR_ORGANISATION_UUID/letters'
access_token = 'INSERT_YOUR_ACCESS_TOKEN_HERE'

response = requests.get(url_file_upload, headers = {
  'Authorization': 'Bearer {}'.format(access_token),
})
data = json.loads(response.text)['data']
file_url = data['attributes']['url']
file_url_signature = data['attributes']['url_signature']

file = open('path_to_your_file.pdf', 'rb')
requests.put(file_url, data=file)
file.close()

payload = {
  'data': {
    'type': 'letters',
    'attributes': {
      'file_original_name': 'your_filename.pdf',
      'file_url': file_url,
      'file_url_signature': file_url_signature,
      'address_position': 'left',
      'auto_send': False
    }
  }
}

requests.post(
  url_letters,
  json.dumps(payload),
  headers = {
    'Content-Type': 'application/vnd.api+json',
    'Authorization': 'Bearer {}'.format(access_token)
  }
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

$organisationUUID = 'INSERT_YOUR_ORGANISATION_UUID_HERE';
$accessToken = 'INSERT_YOUR_ACCESS_TOKEN_HERE';
$fileOriginalName = 'your_filename.pdf';
$filePath = 'path_to_your_file.pdf';

// Step 1: GET request to retrieve upload URL and signature
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://api.pingen.com/file-upload");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  "Authorization: Bearer $accessToken"
]);

$response = curl_exec($ch);
if (curl_errno($ch)) {
  echo 'Error:' . curl_error($ch);
  exit;
}
curl_close($ch);

$responseData = json_decode($response, true);
if (!isset($responseData['data']['attributes']['url']) || !isset($responseData['data']['attributes']['url_signature'])) {
  echo 'Failed to retrieve URL and signature.';
  exit;
}

$uploadUrl = $responseData['data']['attributes']['url'];
$uploadUrlSignature = $responseData['data']['attributes']['url_signature'];

// Step 2: PUT request to upload the file
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $uploadUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, fopen($filePath, 'r'));
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filePath));

$response = curl_exec($ch);
if (curl_errno($ch)) {
  echo 'Error:' . curl_error($ch);
  exit;
}
curl_close($ch);

$data = [
  'data' => [
    'type' => 'letters',
    'attributes' => [
      'file_original_name' => $fileOriginalName,
      'file_url' => $uploadUrl,
      'file_url_signature' => $uploadUrlSignature,
      'address_position' => 'left',
      'auto_send' => false,
    ]
  ]
];

// Step 3: POST request to create the letter
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://api.pingen.com/organisations/$organisationUUID/letters");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

$headers = [
  'Content-Type: application/vnd.api+json',
  "Authorization: Bearer $accessToken"
];

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
if (curl_errno($ch)) {
  echo 'Error:' . curl_error($ch);
}
curl_close($ch);

echo $response;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
curl \
  -X GET "https://api.pingen.com/file-upload" \
  -H "Authorization: Bearer INSERT_YOUR_ACCESS_TOKEN_HERE"

# Extract data.attributes.url and data.attributes.url_signature from response

curl -X PUT -T path_to_your_file.pdf "INSERT_URL_FROM_INITIAL_CURL_REQUEST"

curl \
  -X POST "https://api.pingen.com/organisations/INSERT_YOUR_ORGANISATION_UUID_HERE/letters" \
  -H "Content-Type: application/vnd.api+json" \
  -H "Authorization: Bearer INSERT_YOUR_ACCESS_TOKEN_HERE" \
  --data-binary @- << EOF
  {
    "data": { \
      "type": "letters", \
      "attributes": { \
        "file_original_name": "your_filename.pdf", \
        "file_url": "INSERT_URL_FROM_INITIAL_CURL_REQUEST", \
        "file_url_signature": "INSERT_URL_SIGNATURE_FROM_INITIAL_CURL_REQUEST", \
        "address_position": "left", \
        "auto_send": false \
      } \
    } \
  }
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import (
  "bytes"
  "encoding/json"
  "fmt"
  "io"
  "net/http"
  "os"
)

func main() {
  urlFileUpload := "https://api.pingen.com/file-upload"
  urlLetters := "https://api.pingen.com/organisations/YOUR_ORGANISATION_UUID/letters"
  accessToken := "INSERT_YOUR_ACCESS_TOKEN_HERE"

  // Step 1: GET file upload endpoint
  req, err := http.NewRequest("GET", urlFileUpload, nil)
  if err != nil {
    fmt.Println("Error creating GET request:", err)
    return
  }
  req.Header.Set("Authorization", "Bearer "+accessToken)

  client := &http.Client{}
  resp, err := client.Do(req)
  if err != nil {
    fmt.Println("Error sending GET request:", err)
    return
  }
  defer resp.Body.Close()

  if resp.StatusCode != http.StatusOK {
    fmt.Printf("Failed to fetch file upload data, status: %d\n", resp.StatusCode)
    return
  }

  // Parse the response
  var fileUploadData struct {
    Data struct {
      Attributes struct {
        URL string `json:"url"`
        URLSignature string `json:"url_signature"`
      } `json:"attributes"`
    } `json:"data"`
  }
  if err := json.NewDecoder(resp.Body).Decode(&fileUploadData); err != nil {
    fmt.Println("Error decoding file upload response:", err)
    return
  }

  fileURL := fileUploadData.Data.Attributes.URL
  fileURLSignature := fileUploadData.Data.Attributes.URLSignature

  // Step 2: PUT file to the signed URL
  file, err := os.Open("path_to_your_file.pdf")
  if err != nil {
    fmt.Println("Error opening file:", err)
    return
  }
  defer file.Close()

  req, err = http.NewRequest("PUT", fileURL, file)
  if err != nil {
    fmt.Println("Error creating PUT request:", err)
    return
  }

  resp, err = client.Do(req)
  if err != nil {
    fmt.Println("Error sending PUT request:", err)
    return
  }
  defer resp.Body.Close()

  if resp.StatusCode != http.StatusOK {
    fmt.Printf("Failed to upload the file, status: %d\n", resp.StatusCode)
    return
  }

  // Step 3: POST letter details to the API
  payload := map[string]interface{}{
    "data": map[string]interface{}{
      "type": "letters",
      "attributes": map[string]interface{}{
        "file_original_name": "your_filename.pdf",
        "file_url": fileURL,
        "file_url_signature": fileURLSignature,
        "address_position": "left",
        "auto_send": false,
      },
    },
  }
  payloadBytes, err := json.Marshal(payload)
  if err != nil {
    fmt.Println("Error marshalling payload:", err)
    return
  }

  req, err = http.NewRequest("POST", urlLetters, bytes.NewBuffer(payloadBytes))
  if err != nil {
    fmt.Println("Error creating POST request:", err)
    return
  }
  req.Header.Set("Content-Type", "application/vnd.api+json")
  req.Header.Set("Authorization", "Bearer "+accessToken)

  resp, err = client.Do(req)
  if err != nil {
    fmt.Println("Error sending POST request:", err)
    return
  }
  defer resp.Body.Close()

  if resp.StatusCode == http.StatusCreated {
    fmt.Println("Letter successfully created!")
  } else {
    fmt.Printf("Failed to create the letter, status: %d\n", resp.StatusCode)
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import (java.io.*; java.net.HttpURLConnection; java.net.URL;)
import org.json.JSONObject;

public class UploadAndCreateLetter {
  public static void main(String[] args) {
    String urlFileUpload = "https://api.pingen.com/file-upload";
    String urlLetters = "https://api.pingen.com/organisations/YOUR_ORGANISATION_UUID/letters";
    String accessToken = "INSERT_YOUR_ACCESS_TOKEN_HERE";
    String filePath = "path_to_your_file.pdf";
    String fileName = "your_filename.pdf";

    try {
      // Step 1: Get upload URL
      URL url = new URL(urlFileUpload);
      HttpURLConnection connection = (HttpURLConnection) url.openConnection();
      connection.setRequestMethod("GET");
      connection.setRequestProperty("Authorization", "Bearer " + accessToken);

      int statusCode = connection.getResponseCode();
      if (statusCode != HttpURLConnection.HTTP_OK) {
        System.out.printf("Failed to get file upload URL. HTTP Status Code: %d%n", statusCode);
        return;
      }

      StringBuilder response = new StringBuilder();
      try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
        String line;
        while ((line = br.readLine()) != null) {
          response.append(line);
        }
      }

      JSONObject data = new JSONObject(response.toString())
        .getJSONObject("data")
        .getJSONObject("attributes");
      String fileUrl = data.getString("url");
      String fileUrlSignature = data.getString("url_signature");

      connection.disconnect();

      // Step 2: Upload file
      uploadFile(fileUrl, filePath);

      // Step 3: Create letter
      createLetter(urlLetters, accessToken, fileName, fileUrl, fileUrlSignature);

    } catch (Exception e) {
      System.err.println("Error occurred: " + e.getMessage());
      e.printStackTrace();
    }
  }

  private static void uploadFile(String fileUrl, String filePath) throws IOException {
    File file = new File(filePath);
    if (!file.exists()) {
      System.err.println("File not found: " + filePath);
      return;
    }

    URL uploadUrl = new URL(fileUrl);
    HttpURLConnection connection = (HttpURLConnection) uploadUrl.openConnection();
    connection.setRequestMethod("PUT");
    connection.setDoOutput(true);

    try (OutputStream os = connection.getOutputStream();
      FileInputStream fis = new FileInputStream(file)) {
      byte[] buffer = new byte[1024];
      int bytesRead;
      while ((bytesRead = fis.read(buffer)) != -1) {
        os.write(buffer, 0, bytesRead);
      }
    }

    int uploadStatusCode = connection.getResponseCode();
    if (uploadStatusCode != HttpURLConnection.HTTP_OK && uploadStatusCode != HttpURLConnection.HTTP_CREATED) {
      System.out.printf("File upload failed. HTTP Status Code: %d%n", uploadStatusCode);
    } else {
      System.out.println("File uploaded successfully.");
    }

    connection.disconnect();
  }

  private static void createLetter(String urlLetters, String accessToken, String fileName, String fileUrl,
    String fileUrlSignature) throws IOException {
    URL url = new URL(urlLetters);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("POST");
    connection.setRequestProperty("Content-Type", "application/vnd.api+json");
    connection.setRequestProperty("Authorization", "Bearer " + accessToken);
    connection.setDoOutput(true);

    JSONObject payload = new JSONObject();
    JSONObject data = new JSONObject();
    JSONObject attributes = new JSONObject();

    attributes.put("file_original_name", fileName);
    attributes.put("file_url", fileUrl);
    attributes.put("file_url_signature", fileUrlSignature);
    attributes.put("address_position", "left");
    attributes.put("auto_send", false);

    data.put("type", "letters");
    data.put("attributes", attributes);
    payload.put("data", data);

    try (OutputStream os = connection.getOutputStream()) {
      os.write(payload.toString().getBytes());
    }

    int statusCode = connection.getResponseCode();
    if (statusCode == HttpURLConnection.HTTP_CREATED) {
      System.out.println("Letter created successfully.");
    } else {
      System.out.printf("Failed to create letter. HTTP Status Code: %d%n", statusCode);
    }

    connection.disconnect();
  }
}
Graem Lourens, CTO van Pingen

“We maken het ontwikkelaars graag makkelijk – niet alleen bij de integratie, maar ook op de lange termijn. Een tevreden ontwikkelaar is onze beste verkoopstrategie.”

Graem Lourens, medeoprichter en CTO van Pingen

Gebruiksklare componenten

Voorgeconfigureerde modules zorgen voor een snelle setup.

Eenvoudige integratie

Intuïtieve WebApp voor naadloos API-beheer.

Altijd up to date in de toekomst

Garandeert compatibiliteit met de evolutie van Pingen.

Tijd- en kostenbesparingen

Minimaliseer ontwikkelings- en onderhoudsinspanningen.

Meerdere programmeertalen

Vanuit ons beschikbaar voor PHP, GO, Python en .Net.

Duidelijke documentatie

Duidelijke handleidingen voor snelle implementatie.

Krachtige SDK's

Onze SDK's zijn ontworpen om de API-integratie te vereenvoudigen, kosten en tijd te besparen, en tegelijkertijd een soepele en betrouwbare ervaring te bieden op verschillende platforms en in meerdere talen.

Bekijk onze SDK's

Real-time updates via webhooks

Pingen biedt automatische webhookmeldingen met realtime updates per brief, zodat je kunt reageren zonder de API actief te monitoren.

Webhooks-voorbeelden
Pingen-webhooksdashboard met details van een onbestelbare postgebeurtenis, JSON-payload en successtatus

Sandboxomgeving voor developers

Pingen biedt een stagingomgeving die het productiesysteem exact nabootst, maar volledig gescheiden is. Zo kun je alles kostenloos en zonder risico’s testen voordat je live gaat.

Testen zonder risico

Gebruik onze staging om integraties veilig te testen zonder live data te beïnvloeden of kosten te maken.

Illustratie van de staging-omgeving

Volledige functie-simulatie

Pingen's staging bootst alle functies na, zodat je je werkprocessen veilig kunt testen, van het verzenden tot het volgen van brieven.

Debug voor livegang

Identificeer en los problemen op in een gecontroleerde omgeving voordat je live gaat, waardoor fouten in de productie worden vermeden.

Ontwikkelaarsvriendelijk

Onze sandbox is ontworpen voor ontwikkelaars om integratietests te vereenvoudigen en de ontwikkeling te versnellen.

Aan de slag met Pingen API

1

Meld je gratis aan

Maak een gratis account aan om aan de slag te gaan met Pingen en toegang te krijgen tot onze WebApp en de brief API.

2

Verkrijg je API-key

Maak een Developer App in Pingen aan om de Client-ID en Client-Secret te ontvangen die nodig zijn voor API-authenticatie.

3

Integreer de API

Gebruik een van de SDK's of maak je eigen integratie op basis van onze API-documentatie en CURL-voorbeelden.

4

Test en ga live

Test je integratie in onze stagingomgeving en volg de gebeurtenissen via de WebApp en webhookmeldingen.