Developers

Four steps
to connect your product

Sign a token for each user, import your OpenAPI file, label your actions, then add the assistant to your web app with one script tag.

Step 1

Sign tokens
on your backend

Orrin never sees your users’ passwords or sessions. Your backend signs a short lived token for the signed in user with your workspace’s private key, and the assistant checks it on every request: the signature against your active keys, the audience, the expiry and the fifteen minute limit.

Token claims

kid
Header. The key id shown in the console when you generated the key
sub
The user’s id in your system. Required
aud
orrin. Required
iat, exp
Required. exp at most fifteen minutes after iat
scopes
What the user may do, as an array or a space separated string
role
The user’s role in your product, shown when a preview is refused
company
The customer company the user belongs to. Optional
JavaScriptNode, jose
// Node with jose. Your route, behind your own sign in. The token lives ten minutes.
import { SignJWT, importPKCS8 } from "jose";
const privateKey = await importPKCS8(process.env.ORRIN_PRIVATE_KEY, "EdDSA");

app.get("/api/orrin-token", requireSession, async (req, res) => {
  const token = await new SignJWT({ company: req.user.companyId, role: req.user.role, scopes: req.user.scopes })
    .setProtectedHeader({ alg: "EdDSA", kid: ORRIN_KEY_ID })
    .setSubject(req.user.id)
    .setAudience("orrin")
    .setIssuedAt()
    .setExpirationTime("10m")
    .sign(privateKey);
  res.type("text/plain").send(token);
});
PythonFastAPI, PyJWT
# FastAPI with PyJWT (pip install pyjwt cryptography). The token lives ten minutes.
import time
import jwt

@app.get("/api/orrin-token", response_class=PlainTextResponse)
def orrin_token(user: User = Depends(current_user)):
    now = int(time.time())
    claims = {"sub": str(user.id), "company": user.company_id, "role": user.role, "scopes": user.scopes,
              "iat": now, "exp": now + 600, "aud": "orrin"}
    return jwt.encode(claims, ORRIN_PRIVATE_KEY, algorithm="EdDSA", headers={"kid": ORRIN_KEY_ID})

Step 2

Import
your OpenAPI file

Upload or link your OpenAPI specification in the console. Each endpoint becomes a candidate tool with a name, a description and typed parameters taken from your schema. Nothing is exposed until you choose it.

Step 3

Label
your actions

Mark each exposed endpoint Read, Write or Sensitive and try a preview in the console. In your product, a preview is prepared only when the user’s scopes cover the operation: resource:read for a Read operation, resource:write for Write and Sensitive, where the resource is the first segment of its path. POST /work-orders needs work_orders:write, and *:read or *:write cover every resource.

Step 4

Add the assistant
to your product

Two tags put a button in the corner of your web app that opens the assistant in a panel. The panel asks your page for the user’s token through orrinSettings.getToken, answers from your documentation with citations and previews actions within the user’s scopes. It loads only on the origins you approved in the console, and your workspace id is on its Embed and theme page.

HTMLAny web app
<!-- On every page where signed in users should see the assistant -->
<script src="https://orrin.live/embed.js" data-workspace="YOUR_WORKSPACE_ID" defer></script>
<script>
  window.orrinSettings = {
    // Called whenever the assistant needs a token: return the one your route signs.
    getToken: () => fetch("/api/orrin-token").then((response) => response.text()),
  };
</script>
JavaScriptOptional controls
// Optional, once the page has loaded
window.Orrin.open();   // also .close() and .toggle()

// Optional attributes on the script tag
// data-label="Help"          the button text (default "Ask")
// data-position="left"       the corner it sits in (default right)
// data-accent="#1f6f5c"      the button colour until your workspace's accent loads

Support

Help when
you need it

Every workspace reaches the Orrin team from Contact Orrin in the console, and the articles cover what to prepare before you connect your product.