SDKs

Node.js SDK

The official Node.js library for Connect with rNet and AI requests. ESM, TypeScript types included, no dependencies.

npm@rnet-ai/rnet-oauth-node· Node.js 18 or later

Install

bash
npm install @rnet-ai/rnet-oauth-node

Create the clients

Use the Client ID and secret from your registered app. The model is chosen when you create the ModelClient.

javascript
import { RNetOAuthClient, ModelClient } from '@rnet-ai/rnet-oauth-node';

const auth = new RNetOAuthClient({
  clientId: process.env.RNET_CLIENT_ID,
  clientSecret: process.env.RNET_CLIENT_SECRET,
  redirectUri: 'https://yourapp.com/callback',
});

const ai = new ModelClient('gemini-2.5-flash-lite');

Start Connect with rNet

javascript
// Create a PKCE pair and keep the verifier in the user's server-side session
const { verifier, challenge } = auth.generatePKCE();
const state = crypto.randomUUID();
req.session.rnet = { verifier, state };

// Send the user to rNet to sign in and approve your app
res.redirect(auth.getAuthorizationUrl(challenge, state));

Exchange the code for tokens

javascript
// GET /callback?code=...&state=...
const { verifier, state } = req.session.rnet;
if (req.query.state !== state) return res.status(400).send('Invalid state');

const tokens = await auth.exchangeCodeForToken(req.query.code, verifier);
req.session.rnet = {
  accessToken: tokens.access_token,
  refreshToken: tokens.refresh_token,
};

Refresh the access token

javascript
const tokens = await auth.refreshAccessToken(session.refreshToken);
session.accessToken = tokens.access_token;
session.refreshToken = tokens.refresh_token; // refresh tokens rotate: always keep the new one

Get the user profile

javascript
const user = await auth.getUserInfo(accessToken);
console.log(user.email, user.name);

Call a model

javascript
const response = await ai.chat({
  contents: [{ role: 'user', parts: [{ text: 'Write a haiku about credits.' }] }],
}, accessToken);

console.log(response);

Stream a response

javascript
const stream = await ai.chatStream(payload, accessToken); // ReadableStream
const reader = stream.getReader();
const decoder = new TextDecoder();

for (;;) {
  const { value, done } = await reader.read();
  if (done) break;
  res.write(decoder.decode(value)); // forward server-sent events to your client
}
res.end();

Handle errors

javascript
try {
  const response = await ai.chat(payload, accessToken);
} catch (err) {
  // SDK errors look like: "Request failed: 402 - Insufficient funds"
  const status = Number(/Request failed: (\d{3})/.exec(err.message)?.[1]);

  if (status === 401) {
    // Access token expired: refresh it and retry once
  } else if (status === 402) {
    // The user is out of credits: ask them to top up at rnetai.org/user-home
  } else if (status === 429) {
    // Too many requests: wait and retry
  } else {
    throw err;
  }
}