Hylo
  • Hylo
  • About
    • ❄️What Makes Hylo Different?
    • 🙋Is Hylo Right for My Group?
    • ❤️Our Values
    • 🌎Bioregional Vision
    • 💪How to get involved
    • ❓FAQ
    • ⭕Community Stewardship Support Program (CSAAS)
    • 👁️Hylo Privacy Policy
      • GDPR Privacy Policy
  • product
    • 🌄Product Journey
    • 🔍Hylo Features
    • Feature Requests + Bug Reports
    • Learning Tracks: Feature Specification
    • Hylo Testing Instructions (Web)
    • Hylo Redesign Testing Instructions (Mobile)
    • Hylo Redesign: Product Updates
  • Guides
    • 🐞Feedback and Support
    • 🚢Hylo Admin Guide
      • 👾Onboarding your Group
        • Setting Up Your Group/s on Hylo
        • Customizing Your Group in Group Settings
        • Group Agreements
        • Roles, Badges, and Responsibilities
        • Responsibilities and Permissions
        • Adjusting Group Privacy and Access Settings
        • Create Custom Views for your Group
        • Set up Group #Topics
        • Link Related & Nested Groups
        • Curate your Group's "Explore Page"
        • Populate Posts in your Group
        • Invite Group Members
      • Removing Members
      • Add/Remove Additional Moderators
      • Managing Join Requests
      • Export your Group Data
      • Delete your Group
      • Moderating Member Posts
      • Create an Announcement
      • Edit your Group's "Explore Page"
    • 🧞‍♀️List of Admin Privileges for Group Stewards
    • 🛡️Building Engagement in your Group
      • Foundations for Group Engagement
      • Creating a Plan for Group Engagement
      • Building Group Engagement
    • 🔃API Documentation
    • 🖇️Zapier Integration on Hylo
    • 🌱Farm Profiles on Hylo
    • 🦄Creating an iframe
    • Transition your Group to the New Hylo
  • Hylo User Manual
    • Joining Hylo
    • Navigate Hylo: The Global Navigation Menu
    • Setting up Your Profile
    • Notifications
    • Member Account Settings
    • The Group Menu
    • Chat on Hylo
    • Posts
    • Topics
    • Explore your Group
    • The Map
    • Related Groups
    • Joining Groups
    • Leaving Groups
    • My Home
    • All My Groups Content
    • The Commons
    • Direct Messaging
  • Partners
    • 🤝Stakeholders Co-Creating Hylo
      • OpenTEAM <> Hylo
      • Holo <> Hylo
Powered by GitBook
On this page
  • Authorization Code flow instructions
  • Client Credentials instructions

Was this helpful?

  1. Guides

API Documentation

PreviousBuilding Group EngagementNextZapier Integration on Hylo

Last updated 1 year ago

Was this helpful?

We have recently launched our MVP of Hylo APIs that can be used by partners to interact with Hylo from third party apps. Currently you have to contact us at if you want access to the APIs. We will send you a client_id and client_secret manually. We are using the oAuth 2.0 and OpenID Connect standards to enable our API access. We primarily support the oAuth 2.0 Authorization Code flow for full API access in most app types, including web apps and natively installed apps. This requires redirecting to Hylo to get permission from a user to access Hylo as them. We also support the Client Credentials flow/grant type for server-to-server interactions that don't require interaction with a user. This allows a web service to use its own credentials, instead of impersonating a user, to authenticate when calling our APIs. We only support limited API calls for this type of connection.

Authorization Code flow instructions

For full API access in most app types, including web apps and natively installed apps.

Authentication

When asking us to give you a client ID and secret key you will also need to send us a list of possible redirect URLs you might use. Then follow the standard oAuth Authorization Code flow, with the following URLs:

  • Authorization URL:

  • Access Token URL:

  1. First make a GET request to the Hylo Authorization URL, this is often done in a popup window, where the user will be asked to give consent to your app accessing their Hylo data.

    • URL parameters are:

      • client_id: the client ID given to you by us

      • redirect_uri: the URL to redirect to after authorization, must match exactly one of the redirect URIs you sent to us when asking for API access

      • response_type: code

      • state (optional): should be a randomly generated string, used to prevent XSRF attacks by making sure that the state string we send back to you is the same one you sent us.

      • code_challenge: required for PKCE (Proof Key for Code Exchange). Instructions for generating here: . We generally require PKCE, but if for some reason your system cannot work with that let us know and we can turn it off for your client.

    • code_challenge_method: S256 (meaning SHA256)

    • scope: space separated list of scopes, detailing what information (claims) you are requesting on the behalf of the user. Options are:

      • openid: required. indicates that the application intends to use OIDC to verify the user's identity. will return a 'sub' claim which is the user ID

      • profile: Returns claims that represent basic profile information for the user, including 'name', 'picture', 'updated_at', and 'website'

      • address: Returns the user's physical address if set.

      • email: returns the user's contact email if set

      • phone: returns the user's contact phone number if set

      • offline_access: should be used by applications that intend to make additional requests on behalf of the user over time, by enabling requesting of refresh tokens.

    • prompt (optional): set to 'consent' to always show the consent screen even if the user has already given permission to your app in the past.

    • Example Authorization request: https://hylo.com/noo/oauth/auth?client_id=CLIENT_ID&redirect_uri=AFTER_LOGIN_REDIRECT_URI&response_type=code&state=xxzxn7h87h87h&code_challenge=wrU4wFWi_3urf1Kg--e-7WuPm5fOqyao1oGt9Tfz6iM&code_challenge_method=S256&scope=openid%20email&prompt=consent

  2. You will receive a response at the redirect_uri that looks like: https://uri.com/redirect?state=xxzxn7h87h87h&code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&scope=openid%20email

  3. If you passed in a state parameter your app should confirm that the state returned from the authorization call matches the state you passed to us.

  4. Exchange the code received above for an access token by making a request to the Access Token URL.

    • URL parameters:

      • code: The authorization code that is returned from the initial request.

      • client_id: the client ID given to you by us

      • client_secret: the client_secret given to you by us

      • redirect_uri: the URL to redirect to with the access token, must match exactly one of the redirect URIs you sent to us when asking for API access

      • grant_type: authorization_code

    • Example access token request:

POST https://hylo.com/noo/oauth/token
Content-Type: application/x-www-form-urlencoded

 client_id=CLIENT_ID
 client_secret=XXXXX
 redirect_uri=REDIRECT_URI
 grant_type=authorization_code
 code_verifier=the code_verifier used to generate the code_challenge in the authorization request above
  • A Successful response will contain these fields in a JSON array:

    • access_token: A token that can be used to access the Hylo API.

    • expires_in: The remaining lifetime of the access token in seconds.

    • id_token: A JWT that contains identity information about the user.

    • scope: The scopes of access granted by the access_token expressed as a list of space-delimited, case-sensitive strings.

    • token_type: Identifies the type of token returned.

    • refresh_token (optional): This field is only present if the scope parameters included offline_access in the authentication request. This can be used to request a new access token when this one expires

  1. Making an API call with the access token:

POST to https://hylo.com/noo/graphql

Headers:

'Authorization: `Bearer ${access_token}`
'Content-Type': 'application/json'

This is a GraphQL based endpoint so you will want to pass in raw POST data in the body.

Example GraphQL query: Querying a Group

NOTE: you will want to pass either a slug or an id to query by. If you pass both only the slug will be used to lookup the group.

{
  "query": "query ($id: ID, $slug: String) { group(id: $id, slug: $slug) { id name slug members { items { id name hasRegistered } } } }",
  "variables": {
    "slug": "GROUP_SLUG"
    "id": GROUP_ID
  }
}

Example GraphQL mutation: Updating a Group (only will succeed on groups that the user is a moderator of)

{
  "query": "mutation ($id: ID, $changes: GroupInput) { updateGroup(id: $id, changes: $changes) { id name slug } }",
  "variables": {
    "id": GROUP_ID,
    "changes": {
      "name": "New Group Name"
    }
  }
}

Client Credentials instructions

For direct server-server to API calls, without user interaction. Here we offer a more limited set of API calls, but with some special abilities.

Authentication

Before making any API calls you must get an auth token

POST to https://hylo.com/noo/oauth/token

Headers:

'Authorization: `Bearer ${access_token}`
'Content-Type': 'application/x-www-form-urlencoded'

Parameters (all required):

  • grant_type = client_credentials

  • client_id = YOUR_ID

  • client_secret = YOUR_SECRET

  • scope = api:write if you want to write data, or api:read if you just want to read it.

This call will return an ACCESS_TOKEN for use in later API calls. This token will expire in 2 hours at which point you will need to make another API call to get a new ACCESS_TOKEN.

For every subsequent API you will need to authorize by passing this token as Bearer Token in the Authorization Header: Authorization: Bearer ACCESS_TOKEN

Create a User

POST to https://hylo.com/noo/user

Headers:

'Authorization: `Bearer ${access_token}`
'Content-Type': 'application/x-www-form-urlencoded'

Parameters:

  • name (required) = Judy Mangrove

  • groupId (optional) = the id of a group to add the user to

  • isModerator (optional) = true to add the user to the group specified by groupId as a moderator

Return value:

On success this will return a JSON object that looks like:

{
    "id": "44692",
    "name": "Judy Mangrove",
    "email": "email@email.com"
}

If there is already a user with this email but they are a not member of the group, this call will send them an invitation to join the group. You will receive: { message: "User already exists, invite sent to group GROUP_NAME" }

If there is already a user with this email and they are already a member of the group: { message: "User already exists, and is already a member of this group" }

If there is already a user with this email and you didn't pass in a group you will receive: { message: "User already exists" }

Create a Group

POST to https://hylo.com/noo/graphql

Headers:

'Authorization: `Bearer ${access_token}`
'Content-Type': 'application/json'

This is a GraphQL based endpoint so you will want the pass in a raw POST data Example GraphQL mutation:

{
  "query": "mutation ($data: GroupInput, $asUserId: ID) { createGroup(data: $data, asUserId: $asUserId) { id name slug } }",
  "variables": {
    "data": {
      "accessibility": 1, // 0 => closed (invite only), 1 => restricted (join request requires approval), 2 => open (anyone can instantly join)
      "description": "This is a long-form description of the group",
      "name": "Test Group",
      "slug": "unique-url-slug",
      "parentIds": [], // group-ids for any parent group of this group
      "visibility": 1, // 0 => hidden (Only members can see), 1 => protected (only members and members of networked groups can see), 2 => public (anyone can see, including external public)
      "location": "12345 Farm Street, Farmville, Iowa, 50129, USA",
      "geoShape": <valid geoJSON>,
      "groupExtensions": [
          {
              "type": "farm-onboarding",
              "data": {
                "farm_email": "test@farm.org",
                farmSchema..., // All the values from the farm schema, keys in snake_case
                "flexible: {
                  hylo: {
                    purpose: "Excellence in animal husbandry and educating folks about the role of grazing livestock in the soil cycle", // One or two sentence statement about the vision or purpose of a farm
                    at_a_glance: ["Event center", "You-pick", "Food Education", "Livestock breeder"],
                    opening_hours: "1-5 M-F, 10-6 Weekends", // String descriptor
                    open_to_public: true, // Boolean,
                    public_offerings: ["Farmstand", "Gift shop", "Farm tours", "Workshops"]
                  }
                }
              }
          }
      ],
      "moderatorDescriptor": "Steward", // Default is Moderator
      "moderatorDescriptorPlural": "Stewards", // Default is Moderators
      "settings": {
        locationDisplayPrecision: precise, //   precise => precise location displayed, near => location text shows nearby town/city and coordinate shifted, region => location not shown on map at all and location text shows nearby city/region
        publicMemberDirectory: false, // Boolean
      },
      "type": <valid type or empty for default group type>,
      "typeDescriptor": "Ranch", // Group is the default
      "typeDescriptorPlural": "Ranches" // Groups is the default
    },
    "asUserId": <valid hylo userId>
  }
}

Update a Group

POST to https://hylo.com/noo/graphql

Headers:

'Authorization: `Bearer ${access_token}`
'Content-Type': 'application/json'

This is a GraphQL based endpoint so you will want the pass in a raw POST data Example GraphQL mutation:

{
  "query": "mutation ($id: ID, $changes: GroupInput, $asUserId: ID) { updateGroup(id: $id, changes: $changes, asUserId: $asUserId) { id name slug } }",
  "variables": {
    "id": GROUP_ID,
    "changes": {
      "name": "New Name"
    },
    "asUserId": USER_ID
  }
}

Add a Person to a Group

POST to https://hylo.com/noo/graphql

Headers:

'Authorization: `Bearer ${access_token}`
'Content-Type': 'application/json'

This is a GraphQL based endpoint so you will want the pass in a raw POST data Example GraphQL mutation:

{
  "query": "mutation ($userId: ID, $groupId: ID, $role: Int) { addMember(userId: $userId, groupId: $groupId, role: $role) { success error } }",
  "variables": {
    "groupId": USER_ID,
    "groupId": GROUP_ID,
    "role": 0 // 0 = regular member, 1 = Moderator
  }
}

Query a Group

POST to https://hylo.com/noo/graphql

Headers:

'Authorization: `Bearer ${access_token}`
'Content-Type': 'application/json'

This is a GraphQL based endpoint so you will want the pass in a raw POST data Example GraphQL query: NOTE: you will want to pass either a slug or an id to query by. If you pass both only the slug will be used to lookup the group.

{
  "query": "query ($id: ID, $slug: String) { group(id: $id, slug: $slug) { id name slug members { items { id name hasRegistered } } } }",
  "variables": {
    "slug": "GROUP_SLUG"
    "id": GROUP_ID
  }
}

Query a Person

POST to https://hylo.com/noo/graphql

Headers:

'Authorization: `Bearer ${access_token}`
'Content-Type': 'application/json'

This is a GraphQL based endpoint so you will want the pass in a raw POST data Example GraphQL query: NOTE: you will want to pass either an email or an id to query by. If you pass both only the id will be used to lookup the person.

{
  "query": "query ($id: ID, $email: String) { person(id: $id, email: $email) { id name hasRegistered } }",
  "variables": {
    "email": "test@hello.com"
    "id": PERSON_ID
  }
}

Full GraphQL schema information can be found here:

resource = the server URL you are making the call to (e.g. , , or )

email (required) =

🔃
hello@hylo.com
https://hylo.com/noo/oauth/auth
https://hylo.com/noo/oauth/token
https://www.valentinog.com/blog/challenge/
https://github.com/Hylozoic/hylo-node/blob/dev/api/graphql/schema.graphql
https://hylo.com
https://staging.hylo.com
https://localhost:3000
email@email.com