Routing, geocoding, isochrones, matrix, and route optimization from the GraphHopper Directions API.
Bring your own key. This API needs your own GraphHopper Directions key - get one from the provider, add it once below, and the proxy injects it on every call. Your OmniStream plan covers the unified SDK, key storage, and proxy - the provider's own rate limits still apply to your key.
This is a community listing. If you own this API, you can request ownership.
npm install omnistream-sdkimport { OmniClient } from "omnistream-sdk";
const omni = new OmniClient({ token: process.env.OMNI_KEY! });
// One key reaches every API on the marketplace.
const data = await omni.call("graphhopper/solveClusteringProblem");One install, one key - the same client calls every API on the marketplace.
POST Cluster Endpoint
Batch Cluster Endpoint
GET Batch Solution Endpoint
Geocoding Endpoint
Isochrone Endpoint
Map-match a GPX file
/**
* GraphHopperDirections - generated by OmniStream from GraphHopper Directions's OpenAPI spec.
* One typed method per endpoint. A single Omni key reaches the API.
*/
const DEFAULT_BASE = "https://grid.skinvaults.online/v1/proxy/graphhopper";
export class GraphHopperDirectionsError extends Error {
status: number;
code?: string;
constructor(status: number, code: string | undefined, message?: string) {
super(message || `GraphHopperDirections error ${status}`);
this.name = "GraphHopperDirectionsError";
this.status = status;
this.code = code;
}
}
export interface GraphHopperDirectionsOptions {
baseUrl?: string;
fetch?: typeof fetch;
timeoutMs?: number;
}
export class GraphHopperDirections {
/** @param token Your OmniStream key (one key for every API). */
constructor(private token: string, private opts: GraphHopperDirectionsOptions = {}) {
if (!token) throw new Error("GraphHopperDirections: token is required");
}
rateLimit: { remainingMinute?: number; remainingDay?: number } | null = null;
private async _request(method: string, path: string, { params, body }: { params?: Record<string, unknown>; body?: unknown } = {}): Promise<any> {
const f = this.opts.fetch ?? globalThis.fetch;
const url = new URL((this.opts.baseUrl ?? DEFAULT_BASE).replace(/\/+$/, "") + path);
if (params) for (const [k, v] of Object.entries(params)) if (v != null) url.searchParams.set(k, String(v));
const headers: Record<string, string> = { "x-omni-key": this.token };
if (body !== undefined) headers["content-type"] = "application/json";
const res = await f(url, { method, headers, body: body !== undefined ? JSON.stringify(body) : undefined });
this.rateLimit = {
remainingMinute: Number(res.headers.get("x-ratelimit-remaining-minute")) || undefined,
remainingDay: Number(res.headers.get("x-ratelimit-remaining-day")) || undefined,
};
const data = await res.json().catch(() => ({}));
if (!res.ok) throw new GraphHopperDirectionsError(res.status, data?.error?.code, data?.error?.message);
return data.data ?? data;
}
/** POST Cluster Endpoint */
solveClusteringProblem(body: unknown): Promise<any> {
return this._request("POST", "/cluster", { body });
}
/** Batch Cluster Endpoint */
asyncClusteringProblem(body: unknown): Promise<any> {
return this._request("POST", "/cluster/calculate", { body });
}
/** GET Batch Solution Endpoint */
getClusterSolution(params: { "jobId": string }): Promise<any> {
return this._request("GET", "/cluster/solution/{jobId}", { params });
}
/** Geocoding Endpoint */
getGeocode(params: { "q"?: string; "locale"?: string; "limit"?: number; "reverse"?: boolean; "debug"?: boolean; "point"?: string; "provider"?: string }): Promise<any> {
return this._request("GET", "/geocode", { params });
}
/** Isochrone Endpoint */
getIsochrone(params: { "point": string; "time_limit"?: number; "distance_limit"?: number; "vehicle"?: string; "buckets"?: number; "reverse_flow"?: boolean; "weighting"?: string }): Promise<any> {
return this._request("GET", "/isochrone", { params });
}
/** Map-match a GPX file */
postGPX(params: { "gps_accuracy"?: number; "vehicle"?: string }): Promise<any> {
return this._request("POST", "/match", { params });
}
/** GET Matrix Endpoint */
getMatrix(params: { "point"?: unknown[]; "from_point"?: unknown[]; "to_point"?: unknown[]; "point_hint"?: unknown[]; "from_point_hint"?: unknown[]; "to_point_hint"?: unknown[]; "snap_prevention"?: unknown[]; "curbside"?: unknown[]; "from_curbside"?: unknown[]; "to_curbside"?: unknown[]; "out_array"?: unknown[]; "vehicle"?: string; "fail_fast"?: boolean; "turn_costs"?: boolean }): Promise<any> {
return this._request("GET", "/matrix", { params });
}
/** POST Matrix Endpoint */
postMatrix(body: unknown): Promise<any> {
return this._request("POST", "/matrix", { body });
}
/** Batch Matrix Endpoint */
calculateMatrix(body: unknown): Promise<any> {
return this._request("POST", "/matrix/calculate", { body });
}
/** GET Batch Matrix Endpoint */
getMatrixSolution(params: { "jobId": string }): Promise<any> {
return this._request("GET", "/matrix/solution/{jobId}", { params });
}
/** GET Route Endpoint */
getRoute(params: { "point": unknown[]; "point_hint"?: unknown[]; "snap_prevention"?: unknown[]; "vehicle"?: string; "curbside"?: unknown[]; "turn_costs"?: boolean; "locale"?: string; "elevation"?: boolean; "details"?: unknown[]; "optimize"?: string; "instructions"?: boolean; "calc_points"?: boolean; "debug"?: boolean; "points_encoded"?: boolean; "ch.disable"?: boolean; "weighting"?: string; "heading"?: unknown[]; "heading_penalty"?: number; "pass_through"?: boolean; "block_area"?: string; "avoid"?: string; "algorithm"?: string; "round_trip.distance"?: number; "round_trip.seed"?: number; "alternative_route.max_paths"?: number; "alternative_route.max_weight_factor"?: number; "alternative_route.max_share_factor"?: number }): Promise<any> {
return this._request("GET", "/route", { params });
}
/** POST Route Endpoint */
postRoute(body: unknown): Promise<any> {
return this._request("POST", "/route", { body });
}
/** Coverage information */
getrouteInfo(): Promise<any> {
return this._request("GET", "/route/info", {});
}
/** POST route optimization problem */
solveVRP(body: unknown): Promise<any> {
return this._request("POST", "/vrp", { body });
}
/** POST route optimization problem (batch mode) */
asyncVRP(body: unknown): Promise<any> {
return this._request("POST", "/vrp/optimize", { body });
}
/** GET the solution (batch mode) */
getSolution(params: { "jobId": string }): Promise<any> {
return this._request("GET", "/vrp/solution/{jobId}", { params });
}
}
export default GraphHopperDirections;
No reviews yet. Be the first to rate this API.
Yes. GraphHopper Directions uses apiKey authentication, so you bring your own key from the provider. You store it once on OmniStream and the proxy injects it into every call, so your code only ever sends your Omni key.
Routing, geocoding, isochrones, matrix, and route optimization from the GraphHopper Directions API. It exposes 16 endpoints over POST, GET, including POST /cluster, POST /cluster/calculate, GET /cluster/solution/{jobId}.
Install the OmniStream SDK for your language and call GraphHopper Directions through it. The client is generated from this API's OpenAPI spec, so parameters and responses are fully typed, and the same client also calls every other API in the marketplace.
You can start on the free plan. OmniStream charges for the unified SDK, key storage and proxy rather than for GraphHopper Directions itself, and GraphHopper Directions's own rate limits still apply to your provider key.
API v1: DocSpring is a service that helps you fill out and sign PDF templates.
GET Matrix Endpoint
POST Matrix Endpoint
Batch Matrix Endpoint
GET Batch Matrix Endpoint
GET Route Endpoint
POST Route Endpoint
Coverage information
POST route optimization problem
POST route optimization problem (batch mode)
GET the solution (batch mode)