@remedy-grc/sdk
v1.0.0
Published
Server-side client for the Remedy v1 API
Readme
Remedy SDK 1.0.0
Install and authenticate
Download the language client and models from /sdk/. These are source releases, not published registry packages.
- TypeScript:
client.ts,models.ts; Node 20+ with TypeScript execution support. - Python:
remedy.py,models.py; Python 3.10+, no dependencies. - Java:
Client.java,Models.java; Java 17+ and Jackson Databind. Put sources underai/remedy/.
Set REMEDY_API_KEY and REMEDY_API_BASE_URL in your server environment. Obtain the base URL from Administration → API Integrations → REST API → Versioned developer SDK. Never put private keys in browser code.
import { Client } from './client.ts';
import type { RiskRegister } from './models.ts';
const client = new Client();
console.log((await client.whoami()).data);
for await (const risk of client.iterate<RiskRegister>('risk_register')) {
console.log(risk.risk_id, risk.risk_title);
}from remedy import Client
client = Client()
print(client.whoami()['data'])
for risk in client.iterate('risk_register'):
print(risk['risk_id'], risk['risk_title'])import ai.remedy.Client;
import java.util.Map;
public class Quickstart {
public static void main(String[] args) throws Exception {
Client client = new Client();
System.out.println(client.whoami().path("data"));
for (var risk : client.iterate("risk_register", Map.of("limit", "50"))) {
System.out.println(risk.path("risk_title").asText());
}
}
}Identity returns { data: { key_name, tenant_id, scopes, authenticated: true }, error: null, request_id }. List returns { data: [...], error: null, request_id, pagination: { next_cursor, has_more, limit, sort, direction } }.
Methods
whoami(): current key identity.list(resource, params): array envelope. Parameters: limit (default 50, 1–100), cursor, dir (asc/desc), status where supported.get(resource, id): one record envelope; foreign/unavailable IDs return 404.create(resource, body, idempotencyKey): risks/issues only. Python usesidempotency_key. Java takes an explicit nullable token argument. Creates return 201 record envelopes.iterate(resource, params): auto-pagination; async generator in TypeScript, generator in Python, Iterable in Java.
Defaults: three retries; timeout 30 seconds (TypeScript: 30,000 ms), total retry budget 60 seconds. Override maxRetryTime in TypeScript (milliseconds), max_retry_time in Python (seconds), or the fifth Java constructor argument (Duration). All clients expose a typed RateLimitError; other authentication/permission/conflict errors expose code, status, request ID. Redirects are refused. SDK User-Agent headers identify the language and version 1.0.0. Java uses Jackson JsonNode responses and generated Models classes.
Authorization
Each versioned request checks key expiration/revocation, recorded creator's current ERM authority, enabled application, resource scope, and configured exact-match IP allowlist. Keys without a recorded creator must be rotated. An administrator creates, rotates, or revokes credentials; new keys are revealed once. Record reads also enforce the creator's data clearance. RCSA Assessor keys cannot read the unrestricted risk-assessment resource; assigned questionnaire access stays in the application.
Versioned resources
GET: risk_register, risk_assessment, treatment_plan, loss_event, economic_capital, kri, kci, scenarios, issues. POST: risk_register and issues only. See openapi.json for fields. Workflow updates, deletes, and bulk writes are intentionally unavailable in v1 pending dedicated workflow validation.
Create risk: {"risk_title":"Vendor outage","category":"Operational","inherent_likelihood":3,"inherent_impact":4}.
Create issue: {"issue_title":"Review overdue","severity":"High"}.
Pagination and idempotency
Lists sort lexically by stable resource identifier. Pass next_cursor with unchanged filters/direction. Arbitrary filter/sort fields are rejected; cursors are not snapshot tokens.
Every POST requires an Idempotency-Key of 8–128 printable characters. Same key/body replays the original response for 30 days; changed body returns 409. After 30 days, that token represents a new operation. Store and reuse your original key across manual retries. SDKs generate a token when omitted and keep it stable for automatic retries. Mutation, replay state, and access audit are atomic. Expired replay records are cleaned up daily.
Clients retry GET and idempotent POST on network errors and 429/502/503/504 with exponential backoff/jitter. Numeric and HTTP-date Retry-After are honored by all three clients. The total retry budget is bounded; a rate-limit wait exceeding it returns RateLimitError instead of retrying early. Credentials are not logged, redirects are rejected, and errors do not reveal database details.
Errors
401 invalid_key; 403 access_denied/origin_denied/environment_mismatch; 404 not_found; 400 invalid_request; 409 idempotency_conflict; 413 payload_too_large; 405 method_not_allowed; 429 rate_limited; 504 request_timeout; 500 internal_error. Errors return {data:null,error:{code,message,request_id},request_id}. Send support the request ID, never credentials.
Webhooks and environments
Subscribe to sdk.v1.risk_register.created and sdk.v1.issues.created in Administration → Business Event Alerts. A second administrator approves subscriptions. Notifications are durable, deduplicated, and contain resource/record identifiers. Verify X-Remedy-Signature as HMAC-SHA256 of X-Remedy-Timestamp + "." + raw body, reject timestamps outside five minutes, and deduplicate X-Remedy-Delivery. A TypeScript receiver helper is in webhooks.ts. Failed delivery retries up to six attempts; retry checks run hourly only while work exists. Rotate signing secrets and view delivery logs in that screen. Previous x-erm-signature notifications remain compatible but deprecated; see MIGRATION.md.
Request rate limits are planned and will be announced in the changelog. Until then, please keep client request rates reasonable. The clients already honor Retry-After if a 429 is returned.
A separate sandbox with isolated credentials is planned for a future release. Today, requests use your live organization, so use read-only keys while testing. Existing unversioned API and OAuth MCP integrations remain unchanged.
Prepare packages
- TypeScript:
npm install, thennpm packin this SDK directory; package.json builds declarations and JavaScript from the sources. - Python:
python -m buildusing pyproject.toml, then publish with your approved registry account. - Java:
mvn packageusing pom.xml. Maven Central publication additionally needs your verified namespace, release metadata, credentials, and signing setup. The TypeScript package is published on npm as@remedy-grc/sdk(npm install @remedy-grc/sdk). Python and Java packages are not yet published. Licensed under Apache-2.0; see LICENSE.
Security and common tasks
Keep keys on servers, never browser/mobile apps. Rotate every 90 days, use least-privilege scopes and IP allowlists, and revoke unused credentials. list retrieves a batch, get retrieves a returned ID, create accepts a stable operation token, and iterate follows cursors automatically. Test with read-only keys first.
Feedback and support
Documentation: /developers; contact: /contact; email: [email protected]. Check the selected API's health from the documentation status section. Support response times follow your agreement; urgent incidents should be escalated by your organization administrator. Page feedback stays local until you send an email. See CHANGELOG.md and MIGRATION.md. Future removals need advance notice and a migration guide.
