Open Application Platform Docs

Installation

The packages of every language and platform, the first calls and webhook verification.

Current release: 0.2.5. Every package of a release carries the same version. Requirements: Node 20+, iOS 15+, macOS 12+, Android 7+, .NET 8, Python 3.9+, PHP 8.1+, Go 1.21+, Java 17+.

Platform SDK UI kit
JavaScript / TypeScript @superrouteca/sapp @superrouteca/sapp-ui
React @superrouteca/sapp-react @superrouteca/sapp-react/ui
React Native @superrouteca/sapp-react-native @superrouteca/sapp-react-native/ui
Dart / Flutter sapp sapp_ui
Swift (iOS, macOS) SApp SAppUI
Kotlin / Android ca.superroute:sapp, ca.superroute:sapp-android ca.superroute:sapp-ui-android
C# / .NET Superroute.SApp Superroute.SApp.UI, Superroute.SApp.Wpf, Superroute.SApp.WinForms
Python superroute-sapp —
PHP superroute/sapp —
Go github.com/Goodneo-Solutions/sapp-releases/go —
Java ca.superroute:sapp-java —

License: Superroute SDK License

JavaScript / TypeScript

npm install @superrouteca/sapp@0.2.5
npm install @superrouteca/sapp-ui@0.2.5

React

npm install @superrouteca/sapp@0.2.5 @superrouteca/sapp-react@0.2.5 @superrouteca/sapp-ui@0.2.5

React Native

npm install @superrouteca/sapp@0.2.5 @superrouteca/sapp-react-native@0.2.5

Dart / Flutter

dart pub add sapp:0.2.5
flutter pub add sapp_ui:0.2.5

Swift (iOS, macOS)

Add the package in Xcode (File → Add Package Dependencies) or in Package.swift.

.package(url: "https://github.com/Goodneo-Solutions/sapp-releases", from: "0.2.5")
// products: "SApp", "SAppUI"

Kotlin / Android

Add the sApp Maven repository to the repositories of the Gradle build.

repositories {
    maven { url = uri("https://goodneo-solutions.github.io/sapp-releases/maven") }
}
implementation("ca.superroute:sapp:0.2.5")              // JVM
implementation("ca.superroute:sapp-android:0.2.5")      // Android
implementation("ca.superroute:sapp-ui-android:0.2.5")

C# / .NET

dotnet add package Superroute.SApp --version 0.2.5
dotnet add package Superroute.SApp.Wpf --version 0.2.5       # or Superroute.SApp.WinForms

Python

pip install superroute-sapp==0.2.5
# import sapp

PHP

composer require superroute/sapp:0.2.5

Go

go get github.com/Goodneo-Solutions/sapp-releases/go@v0.2.5

Java

Add the sApp Maven repository to the repositories of the Gradle build.

repositories {
    maven { url = uri("https://goodneo-solutions.github.io/sapp-releases/maven") }
}
implementation("ca.superroute:sapp-java:0.2.5")

First call

Create a partner client with the app code, the service provider's client code, an app key for calls before sign-in and a secure token store.

import { createPartnerClient } from '@superrouteca/sapp';

const sr = createPartnerClient({
  appCode: 'p_acme_parcels',
  clientCode: 'k3m9q2',
  appKey: 'sp_appkey_…',
  tokenStore,
  locale: 'en',
});
final sr = PartnerClient(appCode: 'p_acme_parcels', clientCode: 'k3m9q2', appKey: 'sp_appkey_…', tokenStore: store);
let sr = PartnerClient(appCode: "p_acme_parcels", clientCode: "k3m9q2", appKey: "sp_appkey_…", tokenStore: KeychainTokenStore())
val sr = PartnerClient(appCode = "p_acme_parcels", clientCode = "k3m9q2", appKey = "sp_appkey_…", tokenStore = KeystoreTokenStore(context))
using var sr = new PartnerClient("p_acme_parcels", clientCode: "k3m9q2", appKey: "sp_appkey_…", tokenStore: new ProtectedDataTokenStore());

On a server

On a server, an Open client with the Open Platform API key calls the Open Platform capabilities. The API key is a server secret and is never placed in an app.

// JavaScript / Node
import { createOpenClient } from '@superrouteca/sapp';
const open = createOpenClient({ apiKey: process.env.SUPERROUTE_OPEN_KEY });
const place = await open.geoForward({ body: { address: '100 King St W, Toronto' } });
# Python
import os
from sapp import OpenClient

open = OpenClient(api_key=os.environ['SUPERROUTE_OPEN_KEY'])
place = open.api.geo_forward(body={'address': '100 King St W, Toronto'})
// PHP
use Superroute\SApp\OpenClient;

$open = new OpenClient(apiKey: getenv('SUPERROUTE_OPEN_KEY'));
$place = $open->api->geoForward(['address' => '100 King St W, Toronto']);
// Go
import sapp "github.com/Goodneo-Solutions/sapp-releases/go"

open, err := sapp.NewOpenClient(sapp.OpenOptions{APIKey: os.Getenv("SUPERROUTE_OPEN_KEY")})
place, err := open.API.GeoForward(ctx, sapp.GeoForwardParams{Body: map[string]any{"address": "100 King St W, Toronto"}})
// Java
OpenClient open = OpenClient.builder().apiKey(System.getenv("SUPERROUTE_OPEN_KEY")).build();
Object place = open.api.geoForward(Map.of("address", "100 King St W, Toronto"));

The partner client is created the same way in every server language.

# Python
sr = PartnerClient('p_acme_parcels', client_code='k3m9q2', app_key='sp_appkey_…')
// PHP
$sr = new PartnerClient('p_acme_parcels', clientCode: 'k3m9q2', appKey: 'sp_appkey_…');
// Go
sr, err := sapp.NewPartnerClient(sapp.PartnerOptions{AppCode: "p_acme_parcels", ClientCode: "k3m9q2", AppKey: "sp_appkey_…"})
// Java
PartnerClient sr = PartnerClient.builder("p_acme_parcels").clientCode("k3m9q2").appKey("sp_appkey_…").build();

Webhook verification

Every language verifies Superroute webhooks: it checks the signature over the raw body, refuses a timestamp outside the tolerance (300 seconds) so that an old request cannot be replayed, and parses the event from the native body or a CloudEvents envelope.

// JavaScript / Node (also from sapp-react and sapp-react-native)
import { verifyWebhook } from '@superrouteca/sapp';

const event = await verifyWebhook(rawBody, req.headers, process.env.SUPERROUTE_WEBHOOK_SECRET);
# Python
from sapp import verify_webhook

event = verify_webhook(body, headers, secret)
// PHP
use Superroute\SApp\Webhooks;

$event = Webhooks::verify($body, $headers, $secret);
// Go
event, err := sapp.VerifyWebhook(body, r.Header, []string{secret}, sapp.WebhookOptions{})
// Java
WebhookEvent event = Webhooks.verify(body, headers, secret, WebhookOptions.defaults());
Language Call
Dart / Flutter verifyWebhook(body, headers, [secret])
Swift try Webhooks.verify(body:headers:secrets:)
Kotlin Webhooks.verify(body, headers, listOf(secret))
C# / .NET Webhooks.Verify(body, headers, new[] { secret })