Rydmate API

Rydmate Java API

Connect your Java application to Rydmate: read the fleet, hold seats and hear about every change. There is no separate library to install. The API speaks plain HTTPS and JSON, so Java's own tools are enough.

Java 17 or laterAPI reference

Before you start

  • Create an API key in Rydmate under Developers. A key starting with ryd_test_ works on your test account, so nothing you try touches real trips or money.
  • Set it as RYDMATE_API_KEY in your environment. Never put the key in your code or your app.
  • The requests use Java's built-in HTTP client. For JSON, add Jackson: com.fasterxml.jackson.core:jackson-databind. The webhook check needs nothing extra.
1

List your vehicles

The simplest request: every vehicle in the business, with its registration and status. If something goes wrong, the error says what, and carries a reference our team can look up.

ListVehicles.java
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ListVehicles {
    public static void main(String[] args) throws Exception {
        String api = System.getenv().getOrDefault("RYDMATE_API_URL", "https://api.rydmate.com/api/v1");

        HttpRequest request = HttpRequest.newBuilder(URI.create(api + "/vehicles"))
            .header("Authorization", "Bearer " + System.getenv("RYDMATE_API_KEY"))
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());

        JsonNode body = new ObjectMapper().readTree(response.body());
        if (response.statusCode() >= 400) {
            JsonNode error = body.get("error");
            throw new IllegalStateException(error.get("code").asText() + ": " + error.get("message").asText()
                + " (" + error.get("request_id").asText() + ")");
        }

        for (JsonNode vehicle : body.get("data")) {
            System.out.println(vehicle.get("registration_number").asText() + " " + vehicle.get("status").asText());
        }
    }
}

Run it with java ListVehicles.java.

2

Hold a seat without double bookings

Hold a seat on a departure for a passenger. The Idempotency-Key header means that if the connection drops and you send the same request again, you still get one hold, not two.

If another counter took the seat first, Rydmate answers with a conflict instead of booking it twice. Once the passenger has paid, confirm the hold with POST /bookings/{id}/transition and {"to": "CONFIRMED"}.

SellTicket.java
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Map;
import java.util.UUID;

public class SellTicket {
    public static void main(String[] args) throws Exception {
        String api = System.getenv().getOrDefault("RYDMATE_API_URL", "https://api.rydmate.com/api/v1");
        ObjectMapper json = new ObjectMapper();

        String payload = json.writeValueAsString(Map.of(
            "seat_number", "3A",
            "passenger", Map.of("full_name", "Ngozi Okafor"),
            "channel", "PUBLIC_WEB"));

        HttpRequest request = HttpRequest.newBuilder(URI.create(api + "/trips/" + System.getenv("TRIP_ID") + "/bookings"))
            .header("Authorization", "Bearer " + System.getenv("RYDMATE_API_KEY"))
            .header("Content-Type", "application/json")
            // Keep this key and send it again on a retry: you get one hold, never two.
            .header("Idempotency-Key", UUID.randomUUID().toString())
            .POST(HttpRequest.BodyPublishers.ofString(payload))
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());

        JsonNode body = json.readTree(response.body());
        if (response.statusCode() == 409) {
            System.out.println("Seat already taken: " + body.at("/error/message").asText());
        } else if (response.statusCode() >= 400) {
            throw new IllegalStateException(body.at("/error/code").asText() + ": " + body.at("/error/message").asText());
        } else {
            System.out.println("Seat held " + body.at("/data/id").asText());
        }
    }
}
3

Check that an update really came from Rydmate

Rydmate tells your system the moment a trip, ticket, delivery or payment changes. Each update is signed with your endpoint's secret. Check the signature before you act on it, and refuse anything older than five minutes.

RydmateSignature.java
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.HexFormat;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

/** Checks the Rydmate-Signature header on a webhook delivery. */
public final class RydmateSignature {
    public static boolean verify(String secret, String header, byte[] rawBody) throws Exception {
        String t = null;
        String v1 = null;
        for (String part : header.split(",")) {
            String[] kv = part.trim().split("=", 2);
            if (kv.length != 2) continue;
            if (kv[0].equals("t")) t = kv[1];
            if (kv[0].equals("v1")) v1 = kv[1];
        }
        if (t == null || v1 == null || !t.matches("\\d+")) return false;
        if (Math.abs(System.currentTimeMillis() / 1000 - Long.parseLong(t)) > 300) return false;

        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        mac.update((t + ".").getBytes(StandardCharsets.UTF_8));
        String expected = HexFormat.of().formatHex(mac.doFinal(rawBody));
        return MessageDigest.isEqual(
            expected.getBytes(StandardCharsets.UTF_8), v1.getBytes(StandardCharsets.UTF_8));
    }
}

Build on Rydmate

Connect your product to real transport operations

Start on a test account, then go live when your integration is ready. Book a demo to talk through what you are building.