abradeveloper portal
On this page Start here
API, SDK and working integration

One portal for the entire Abra integration.

Search the complete GraphQL schema, copy operations and types, install the JavaScript SDK, explore the example application, and connect device reporting and guarded controls without leaving this page.

1AuthenticateCognito or approved OIDC
2Build from the schemaQueries, mutations, subscriptions and types
3Use the SDK or GraphQLBackend permissions remain authoritative
API access is still required.

Installing the SDK does not enable an Abra API account. Use the endpoint, authentication configuration, permissions, rate limits, and integration terms provisioned for your organization.

01 · The mental model

Four pieces, each with one job

You do not need to understand AWS internals to start. Keep these four pieces separate.

A

Your application

Shows the interface, starts sign-in, asks the SDK for homes, and decides what users can click.

B

Token provider

Returns a current short-lived Cognito token. It belongs to the host app, not the SDK.

C

Abra Connect SDK

Validates inputs, sends GraphQL requests, normalizes errors, and interprets device data.

D

AppSync backend

Authenticates the token and must enforce which homes and devices the signed-in user may access.

In one sentence

Your app handles identity; the SDK handles requests; the backend decides permission.

02 · Installation

Install in one command

Install the hosted SDK build directly in a modern browser or Node.js project.

1

Check Node.js

For command-line and home-automation examples, use Node.js 18 or newer.

node --version
2

Install the SDK build

This package is generated from the same source used by the working example.

npm install https://developer.abralife.com/abra-connect-sdk-0.2.0.tgz
0runtime dependencies
ESMmodern JavaScript modules
TypedTypeScript declarations included
Safe defaultdevice control disabled
03 · Authentication

The SDK never needs a password

Your application signs in using an approved Cognito or OIDC flow. The SDK receives only a short-lived token through a function you provide.

Public configuration is not an AWS credential.

An AppSync URL, AWS region, Cognito user-pool ID, and public browser client ID are visible in every browser build. Never add an AWS access key, secret access key, Cognito client secret, password, or refresh token to a Vite environment variable.

Amplify Auth adapter

If your browser application already uses Amplify Auth, pass its fetchAuthSession function into the included adapter.

import { fetchAuthSession } from "aws-amplify/auth";
import {
  createAbraClient,
  createAmplifyTokenProvider,
} from "@abra-connect/sdk";

const client = createAbraClient({
  endpoint: import.meta.env.VITE_APPSYNC_URL,
  tokenProvider: createAmplifyTokenProvider(fetchAuthSession, {
    tokenType: "access",
  }),
});

Access token

Prefer this for protected APIs when the AppSync configuration supports it. It describes authorization and usually contains less personal information.

ID token

Some existing Cognito/AppSync integrations expect this token. It can contain email and other identity claims, so do not log it.

Any other authentication library

const client = createAbraClient({
  endpoint: "https://your-api.appsync-api.eu-west-1.amazonaws.com/graphql",
  tokenProvider: async () => {
    const session = await yourAuthLibrary.getSession();
    return session.accessToken;
  },
});

The provider runs before every request. That lets your authentication library refresh the session without exposing refresh logic to the SDK.

04 · First data

Load homes and devices

Once the client exists, one request returns the homes visible to the current user.

import {
  createAbraClient,
  flattenDevices,
  getDeviceReport,
  getDeviceStatus,
} from "@abra-connect/sdk";

const client = createAbraClient({
  endpoint: "https://your-api.appsync-api.eu-west-1.amazonaws.com/graphql",
  tokenProvider: async () => getShortLivedToken(),
});

const homes = await client.homes.list();
const devices = flattenDevices(homes);

for (const { device, homeName, areaName } of devices) {
  console.log({
    name: device.name,
    home: homeName,
    area: areaName,
    status: getDeviceStatus(device),
    lastReport: getDeviceReport(device),
  });
}
Example output
{
  name: "Main water valve",
  home: "Demo home",
  area: "Utility room",
  status: { label: "Online", tone: "success" },
  lastReport: { label: "8m ago", tone: "fresh", ... }
}
05 · Example application

A complete React example is included

The hosted application uses this SDK for authentication-token adaptation, home queries, device commands, status interpretation, and reporting age.

Live example

Abra Connect portal

Try demo mode without credentials, or sign in with an Abralife account that has API access.

Open example application
  • Cognito sign-in handled outside the SDK
  • Live homes, hubs, devices, and report ages
  • Capability-driven controls for lights, locks, valves, heat, and charging
  • Separate water-leak alarm reset and valve-operation workflow
  • Responsive iPhone touch scrolling
06 · Device interpretation

Use the data returned by each API

Device reporting age comes from trait timestamps. Home alarm workflows come from client.alarms. Keep those data sources separate instead of manufacturing alarm states.

Freshreported within 2 hours
Agingbetween 2 and 24 hours
Staleolder than 24 hours
Unknownno timestamp returned

Device presentation

getDeviceStatus() summarizes connectivity, battery, fault, and active trait information for lists and dashboards.

Alarm workflow

client.alarms.list(homeId) returns authoritative home alarm records, including their IDs and current states.

const status = getDeviceStatus(device);
const report = getDeviceReport(device);
const reading = getPrimaryReading(device);

console.log(status.label); // "Online", "Offline", "Alarm"...
console.log(report.label); // "Just now", "12m ago", "3d ago"...
console.log(report.exact); // exact local date and time
console.log(reading);      // "22.4°C", "87% battery"...
07 · Guarded control

Read-only unless you opt in

Device mutations can affect locks, valves, heat, lighting, and charging. The SDK therefore refuses all control calls until the host explicitly enables them.

Frontend checks are not authorization.

The AppSync backend must verify the signed-in user's access to the exact home and device on every mutation.

const client = createAbraClient({
  endpoint,
  tokenProvider,
  allowDeviceControl: true,
});

// The valve operation is a device mutation.
// Show a confirmation and verify that it is safe before opening.
await client.devices.setValveOpen("water-valve-device-id", true);

// A leak alarm is a home-level alarm record, not a device command.
const alarms = await client.alarms.list("home-id");
const waterAlarm = alarms.find(
  (alarm) =>
    alarm.__typename === "WaterAlarm"
    && (alarm.state === "ALARM" || alarm.state === "SNOOZED"),
);

if (waterAlarm) {
  // Resolving the alarm does not open the valve.
  await client.alarms.resolve(waterAlarm.id);
}

await client.devices.setOn("light-device-id", true);
await client.devices.setBrightness("light-device-id", 70);
await client.devices.setOpenPercent("blind-device-id", 40);
Two deliberate water-safety actions

First inspect and dry the sensors and resolve the leak alarm. Only then should the user separately confirm opening the water valve.

  1. Check capability: show only commands returned for that device.
  2. Explain the effect: name the home, room, device, and new state.
  3. Confirm: require an intentional user action for safety-sensitive changes.
  4. Wait for result: display command acceptance or the typed error.
  5. Refresh state: do not assume the physical device changed immediately.

Operation names and inputs in this guide are checked against the bundled Abra GraphQL schema.

08 · SDK reference

The complete SDK surface

These are the stable exports intended for application developers.

APIPurposeReturns
createAbraClient(options)Create an immutable client using an HTTPS endpoint and token provider.AbraClient
createAmplifyTokenProvider(fn, options)Adapt Amplify's fetchAuthSession without importing Amplify into the SDK.token provider
client.homes.list()Load homes, hubs, devices, traits, and common attributes.AbraHome[]
client.alarms.list(homeId)Load authoritative home-level alarms and their current state.AbraAlarm[]
client.alarms.resolve(alarmId)Request that an active or snoozed alarm be resolved. Does not move a valve.alarm resolve result
client.graphql(query, variables)Send a custom authorized GraphQL operation.operation data
client.devices.setValveOpen(id, value)Open or close a compatible water valve through Abra's unlocked-state mutation.command result
client.devices.setUnlocked(id, value)Set a compatible lock's unlocked state.command result
client.devices.setOn(id, value)Turn a compatible device on or off.command result
client.devices.setBrightness(id, value)Set brightness from 0 to 100.command result
client.devices.setOpenPercent(id, value)Set a compatible blind or opening position from 0 to 100.command result
client.devices.adjustTemperatureSetpoint(id, delta)Adjust a compatible thermostat by a numeric delta.command result
client.devices.setEvCharging(id, value)Start or stop EV charging.command result
client.devices.setColor(id, color)Set hue and saturation on a compatible light.command result
client.devices.invokeCommand(id, data)Send one of the generic command inputs documented by Abra.command result
flattenDevices(homes)Turn nested homes and hubs into device rows with home/area context.DeviceContext[]
getDeviceStatus(device)Interpret connection, low battery, fault, and active alarm state.label and tone
getDeviceReport(device)Find the newest report timestamp and calculate a human age.age, exact time, tone
getPrimaryReading(device)Choose a useful temperature, humidity, battery, brightness, lock, or power reading.formatted string
buildPortalSummary(homes)Count connected homes, devices, hubs, and attention items.summary object

Custom GraphQL

const data = await client.graphql(
  `query MyHomeIds {
    homes {
      id
      homeInfo { nickname }
    }
  }`,
  {},
  { operation: "Load home names" },
);
09 · Complete GraphQL API

Every operation and type, searchable

This explorer is generated from the complete official Abralife GraphQL SDL. Search by operation, field, type, enum value, or description, then expand any result to copy its exact definition.

Official schema snapshot

Loading synchronization details…

Queries
Mutations
Subscriptions
Objects
Inputs
Enums
Schema index

Loading definitions…

View the complete raw GraphQL SDL
Loading schema.graphql…
10 · Errors

Errors your application can act on

Every SDK error inherits from AbraConnectError and has a stable code.

ABRA_CONFIGURATION_ERROR

Missing endpoint, invalid input, or a control call while control is disabled.

ABRA_AUTHENTICATION_ERROR

The token provider failed or returned no usable token.

ABRA_NETWORK_ERROR

Timeout, DNS, connectivity, browser blocking, or fetch failure.

ABRA_HTTP_ERROR

Non-success HTTP response or a body that was not readable JSON.

ABRA_GRAPHQL_ERROR

Top-level GraphQL errors such as an unauthorized field or invalid query.

ABRA_OPERATION_ERROR

A mutation reached the API but returned business-level command errors.

import {
  AbraAuthenticationError,
  AbraConnectError,
} from "@abra-connect/sdk";

try {
  const homes = await client.homes.list();
} catch (error) {
  if (error instanceof AbraAuthenticationError) {
    showSignInAgain();
  } else if (error instanceof AbraConnectError) {
    showMessage(error.message);
  } else {
    throw error;
  }
}
11 · Homey integration

Connect Abra to Homey Experimental

The Homey integration path lets a customer sign in with their normal Abra account during pairing, discover the homes and devices that account may access, and use those devices in Homey. The Abra API functions are available today; the packaged Homey adapter and its device mappings are experimental functionality.

Normal Abra login is the intended customer experience.

The customer enters their credentials into the approved Abra sign-in flow. The password is never passed to the Abra Connect SDK or stored in the integration. The Homey app receives a renewable user session and supplies only the current short-lived token when it calls the API.

CustomerSigns in with an Abra account
pairs
Homey appRefreshes the user session
HTTPS
Abra APIReturns authorized homes and devices

What the customer does

1

Add Abra in Homey

The pairing flow presents a clear “Log in to Abra” action. No AWS setup or API-key form is shown to the customer.

2

Sign in to Abra

The existing Cognito or approved OIDC flow authenticates the account and returns a renewable session to the Homey integration.

3

Select homes and devices

Homey lists only the homes, areas, hubs, and devices that the signed-in Abra user is permitted to access.

4

Use devices and Flows

Device state, reporting age, alarms, and supported controls can be presented in Homey and used as Flow conditions, triggers, and actions.

Supported API-to-Homey mapping

Abra data or commandHomey representationExperimental behavior
Homes, areas and devicesPairing list and Homey devices grouped by the Abra location metadata.Discover after login and refresh when the customer pairs again.
Connectivity and reporting timestampsAvailability, last-report age, and diagnostic information.Show the timestamp as information; do not manufacture an alarm from age alone.
Lights, blinds, locks and temperatureMatching state, measure, target, and action capabilities when the device reports support.Expose only commands returned for that exact device.
Water valveValve state plus a guarded open or close action.Opening requires an explicit customer action and a fresh result check.
Water, fire and security alarmsAlarm state and Homey Flow triggers.Use authoritative home-level alarm records rather than inferred device labels.
Alarm resolutionA separate guarded Flow action.Resolving a water alarm never opens the valve automatically.
Battery, humidity, power and chargingMeasurements, warnings, status, and supported charging controls.Map only traits present in the API response.

Login and SDK connection

No AWS credentials

The API URL, region, user-pool ID, and public app-client ID are configuration—not AWS IAM credentials. Never put an AWS access key, secret access key, or Cognito client secret in the Homey app.

The host owns the session

The Homey pairing implementation creates and refreshes the Abra session. The SDK only asks for the current access or ID token immediately before each API request.

import Homey from "homey";
import { createAbraClient } from "@abra-connect/sdk";

// abraSession is created by the Homey pairing and login flow.
const client = createAbraClient({
  endpoint: Homey.env.ABRA_APPSYNC_URL,
  tokenProvider: async () => abraSession.getCurrentToken(),
  allowDeviceControl: true,
});

const homes = await client.homes.list();
Keep alarm acknowledgement and valve operation separate.

A customer or Flow may resolve a verified water alarm, but that must not silently reopen the water supply. After the leak source is corrected and every sensor is dry, opening the valve remains a separate, explicit action.

What “Experimental” means

  • API operations are usableAuthenticated reads, reporting age, alarm records, device controls, and alarm resolution are already available through the SDK.
  • Homey adapter is experimentalThe pairing interface, session persistence, device drivers, capability mappings, and Flow cards are the experimental integration layer.
  • State refresh starts with pollingThe current SDK covers GraphQL queries and mutations. Poll only within the provisioned API limits until AppSync subscription support is added.
  • Backend permission remains authoritativeHomey must handle expired sessions and rejected controls, while Abra verifies access to every requested home and device.

This experimental functionality describes the supported path for pilot and customer-developed Homey integrations. It does not imply that an installable Homey package is already included with the JavaScript SDK. See the Homey Apps SDK documentation for Homey application and driver structure.

12 · Home automation

Connect Home Assistant through a local bridge

Home Assistant should not contain an Abralife password. The included Node.js bridge keeps the current token on the bridge machine and exposes a small key-protected local API.

Home AssistantREST sensor
LAN
Local bridgeSDK + bridge key
HTTPS
AppSyncCognito token
1

Open the included example

cd examples/home-assistant
npm install
2

Configure the bridge

Use environment variables or your service manager. Do not commit the actual values.

ABRA_APPSYNC_URL=https://example.appsync-api.eu-west-1.amazonaws.com/graphql
ABRA_TOKEN_FILE=/run/secrets/abra-token
ABRA_BRIDGE_KEY=replace-with-a-long-random-value
ABRA_ALLOW_DEVICE_CONTROL=false
BRIDGE_HOST=127.0.0.1
BRIDGE_PORT=8787
3

Start and check the bridge

npm start
curl http://127.0.0.1:8787/health
4

Add a Home Assistant REST sensor

rest:
  - resource: http://127.0.0.1:8787/api/summary
    scan_interval: 60
    headers:
      x-abra-bridge-key: !secret abra_bridge_key
    sensor:
      - name: Abra connected devices
        value_template: "{{ value_json.summary.onlineDevices }}"
        json_attributes:
          - summary
          - homes
          - alarmsByHome
          - devices
5

Put the bridge key in secrets.yaml

abra_bridge_key: replace-with-the-same-long-random-value
6

Restart Home Assistant

Look for sensor.abra_connected_devices. Its attributes contain the device list and reporting ages.

Optional valve and leak-alarm controls

Enable ABRA_ALLOW_DEVICE_CONTROL=true only after adding explicit confirmations. These endpoints remain separate so an automation cannot accidentally reopen the water supply while acknowledging an alarm.

rest_command:
  abra_set_water_valve:
    url: "http://127.0.0.1:8787/api/devices/{{ device_id }}/valve"
    method: POST
    headers:
      x-abra-bridge-key: !secret abra_bridge_key
      content-type: application/json
    payload: '{"open":{{ open | lower }}}'

  abra_resolve_water_alarm:
    url: "http://127.0.0.1:8787/api/alarms/{{ alarm_id }}/resolve"
    method: POST
    headers:
      x-abra-bridge-key: !secret abra_bridge_key
      content-type: application/json
    payload: "{}"
Keep the bridge local.

Bind to 127.0.0.1 when Home Assistant is on the same host. If containers or another LAN machine require 0.0.0.0, restrict the port with a firewall. Never expose the bridge to the public internet.

The bridge intentionally does not accept an Abralife username or password. For unattended production use, connect ABRA_TOKEN_FILE to an authentication/refresh process approved for your Abra integration.

13 · Production security

Security requirements

Applications using the SDK should implement these safeguards before controlling live devices.

  • API permissionUse the endpoint and integration rights provisioned for your organization.
  • Public app clientNever embed a Cognito client secret in browser or mobile code.
  • Short-lived tokensRefresh sessions through an approved host authentication flow.
  • Secure storageChoose storage appropriate to the host and never log token values.
  • Resolver authorizationCheck user, home, and device ownership on every query and mutation.
  • Control confirmationRequire clear user intent for locks, valves, alarms, heat, and charging.
  • HTTPS and CSPServe production apps over HTTPS with a restrictive Content Security Policy.
  • Rate limitsKeep polling and retries within the documented API limits.
14 · Troubleshooting

Common problems

I receive “token provider returned no usable token”

The user is not signed in, the session expired without a refresh token, or the adapter is asking for a token type that the auth library did not return. Sign in again and confirm tokenType.

AppSync says “Not authorized”

Confirm the token was issued by the user pool configured on the API, is not expired, uses the expected token type, and belongs to a user authorized for the requested field.

Resolving the water alarm did not open the valve

That is intentional. Abra exposes alarm resolution and valve operation as separate actions. Verify that all sensors are dry and the leak source is fixed, then explicitly call setValveOpen(deviceId, true).

The valve or another control is not shown

The example displays only capabilities returned in the device's trait commands. Confirm that the user has control access and the device reports the relevant command.

Home Assistant cannot reach the bridge

If it runs in another container or host, bind the bridge to 0.0.0.0, use the bridge host's LAN address in YAML, and allow only Home Assistant through the firewall.

Homey pairing succeeds but no devices appear

Refresh the session, confirm the signed-in Abra account has access to at least one home, and inspect the typed API error. The integration must not create placeholder devices when the API returns no authorized devices.

Homey says the Abra session has expired

The Homey host must refresh the Cognito or OIDC session before asking the SDK for a token. If renewal fails, return the customer to the Abra login step without retaining or logging the password.

The command method says device control is disabled

This is the safe default. Add confirmation and backend authorization, then create the client with allowDeviceControl: true. The Home Assistant bridge has a separate opt-in environment switch.