JustSignup
← Help

The school API

For a school's own systems to add and remove staff under the school account, for example a nightly sync from the staff OU in Google Workspace (setup steps). Only people the school adds are in it; students and anyone else stay out even when they share the school's email domain.

Base URL: https://justsignup.io/api/org/v1

Key: made on your school page (Dashboard → School → API access), shown once, revocable there at any time. Send it as Authorization: Bearer jsk_…. 300 calls a minute per key.

Sign-in: people you add sign in at justsignup.io with that address, with the emailed one-time link or with Google. Either way they land under the school; there is no password and no invitation to accept.

Errors: plain JSON, {"error": "…"}, with 400 for bad input, 401 for a bad or revoked key and 429 over the rate limit (with retryAfterSeconds).

Show examples in

Check the key

Returns the school's name, domain settings, member counts and the date the plan is paid through. A quick way to see a key works.

curl
curl https://justsignup.io/api/org/v1 \
  -H "Authorization: Bearer jsk_YOUR_KEY"

List staff

Everyone under the school. Each member has an email, a role (admin or member), a status (active, or invited and not yet accepted), how they came in (api, invite, link, domain or owner), whether they have signed in yet, and since when.

curl
curl https://justsignup.io/api/org/v1/members \
  -H "Authorization: Bearer jsk_YOUR_KEY"

Add staff

One person or many. Adding someone twice is harmless ("existing"). They are covered by the school's plan from that moment. There is no invitation to accept: the first time they sign in with that address, with the emailed link or with Google, they land under the school. Nothing is emailed to them by this call.

curl
curl -X POST https://justsignup.io/api/org/v1/members \
  -H "Authorization: Bearer jsk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"members":[{"email":"b.jones@example-school.org","name":"Brittney Jones"},{"email":"r.lee@example-school.org"}]}'

Remove staff

Their account and pages stay theirs; the school simply stops covering them. The admin can't be removed through the API.

curl
curl -X DELETE "https://justsignup.io/api/org/v1/members?email=r.lee@example-school.org" \
  -H "Authorization: Bearer jsk_YOUR_KEY"

Sync a whole list

Makes the API-managed membership match a list, for example everyone in your staff group. Everyone listed is a member afterwards. With removeMissing, people the API added earlier who are no longer listed are removed. People the admin invited by hand, or who joined by link or domain, and the admin, are never touched by a sync. Up to 5,000 addresses a call. Safe to run on a schedule.

curl
curl -X POST https://justsignup.io/api/org/v1/members/sync \
  -H "Authorization: Bearer jsk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"members":[{"email":"b.jones@example-school.org"},{"email":"r.lee@example-school.org"}],"removeMissing":true}'

Response: { "added": 3, "kept": 194, "removed": 1, "details": { ... } }

Set up a nightly sync from Google Workspace

About ten minutes, no code to write. A small script in your own Google Workspace reads everyone in your staff OU once a night and tells JustSignup "these are our staff." People in the OU are covered by the school's plan; people who leave it, or whose Google account is suspended, are removed from the school at the next run. Nothing is emailed to anyone by the sync.

  1. 1
    Make a JustSignup API key

    Sign in at justsignup.io and open School in the top nav. Open Settings at the bottom of the school page, then API access → New key. Copy the key; it starts with jsk_ and is shown once. If you lose it, revoke it there and make a new one.

  2. 2
    Create the script

    Go to script.google.com signed in to your school Google account (you need Workspace admin rights that include reading users) and click New project. Click "Untitled project" at the top left and name it "JustSignup staff sync". Delete everything in Code.gs, paste the script below, and save (the disk icon).

    Code.gs, the whole file
    // JustSignup staff sync for Google Workspace.
    // Reads one organizational unit (OU) from your directory and makes the school account match it.
    // Setup steps: https://justsignup.io/help/school-api#workspace
    // Change OU_PATH to your staff OU. The API key goes in Project Settings > Script Properties, not here.
    
    var OU_PATH = "/Staff"; // your staff OU, exactly as shown under Directory > Organizational units; sub-OUs are included
    var BASE = "https://justsignup.io/api/org/v1";
    
    function syncStaff() {
      var key = PropertiesService.getScriptProperties().getProperty("JUSTSIGNUP_API_KEY");
      if (!key) throw new Error("Add JUSTSIGNUP_API_KEY under Project Settings > Script Properties first.");
    
      var members = [];
      var pageToken;
      do {
        var page = AdminDirectory.Users.list({
          customer: "my_customer",
          query: "orgUnitPath='" + OU_PATH + "' isSuspended=false",
          maxResults: 500,
          orderBy: "email",
          pageToken: pageToken
        });
        (page.users || []).forEach(function (u) {
          if (u.archived) return; // archived accounts are no longer staff
          members.push({ email: u.primaryEmail, name: u.name && u.name.fullName ? u.name.fullName : undefined });
        });
        pageToken = page.nextPageToken;
      } while (pageToken);
    
      if (members.length === 0) {
        throw new Error("No active users found in OU " + OU_PATH + ". Check OU_PATH; nothing was changed in JustSignup.");
      }
    
      var res = UrlFetchApp.fetch(BASE + "/members/sync", {
        method: "post",
        contentType: "application/json",
        headers: { Authorization: "Bearer " + key },
        payload: JSON.stringify({ members: members, removeMissing: true }),
        muteHttpExceptions: true
      });
    
      var status = res.getResponseCode();
      var body = res.getContentText();
      if (status !== 200) throw new Error("JustSignup returned " + status + ": " + body);
      var r = JSON.parse(body);
      Logger.log("Synced " + members.length + " staff from " + OU_PATH + ": added " + r.added + ", kept " + r.kept + ", removed " + r.removed);
    }
    
    // Optional: shows who JustSignup currently has under the school. Changes nothing.
    function listStaff() {
      var key = PropertiesService.getScriptProperties().getProperty("JUSTSIGNUP_API_KEY");
      var res = UrlFetchApp.fetch(BASE + "/members", { headers: { Authorization: "Bearer " + key }, muteHttpExceptions: true });
      Logger.log(res.getContentText());
    }
    
  3. 3
    Set your staff OU

    Change the one line var OU_PATH = "/Staff"; to the path of the OU your staff are in. Find it in the Google Admin console under Directory → Organizational units. The name at the very top of that page is the root of your organization and is not part of the path: an OU shown as Staff under the root is /Staff, and one nested as Employees → Teachers is /Employees/Teachers. Paths are case-sensitive and start with /. OUs inside the one you name are included.

  4. 4
    Put the API key in Script Properties

    In the script editor click the gear icon, Project Settings, in the left sidebar. Under Script Properties click Add script property. Property: JUSTSIGNUP_API_KEY. Value: the jsk_… key from step 1. Click Save script properties. The script reads it from here, so the key is never in the code.

  5. 5
    Turn on the Admin SDK

    Back in the editor (the <> icon), find Services in the left sidebar and click the + next to it. Choose Admin SDK API and click Add. Leave the identifier as AdminDirectory.

  6. 6
    Run it once by hand

    Pick syncStaff in the function dropdown at the top and click Run. The first run asks for permission: choose your school account, click Advanced, then Go to JustSignup staff sync (unsafe), then Allow. "Unsafe" only means your own script hasn't been through Google's app review. The Execution log at the bottom should end with a line like Synced 42 staff from /Staff: added 42, kept 0, removed 0. In JustSignup, School → People now lists everyone from the OU.

  7. 7
    Make it run every night

    Click the clock icon, Triggers, in the left sidebar, then Add Trigger at the bottom right. Function: syncStaff. Event source: Time-driven. Type: Day timer. Pick any hour, for example 2am to 3am. Failure notification: Notify me immediately. Save. From now on the OU is the source of truth for who is in the school account.

If something goes wrong

What a sync does, and doesn't

Still stuck? Reply to any email from us, or use the Help button on your dashboard. A person reads every message.