Skip to content

Student flow ​

Call auth.createUser to register a new student or auth.login to authenticate a returning student. Both mutations return a JWT. Then call viewer.updateUser to save the profile and scholarships.list to fetch matches. To apply, save each requirement with scholarships.submitApplicationRequirementV2 and submit the application with scholarships.applyV2.

Send Authorization: Bearer <token> with viewer.updateUser, scholarships.*, and application mutations. Owlflow associates the account with your organization during registration. Partner identification documents that lookup.

EnvironmentEndpoint
Staginghttps://owlflow.scholarshipowl.tech/graphql
Productionhttps://owlflow.scholarshipowl.com/graphql

Register ​

Header: Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7

Use a new key for each registration attempt. If the request times out, retry it with the same key to avoid creating a duplicate account.

Send the student's real email address. Scholarship providers contact winners at that address. If students don't sign in to ScholarshipOwl directly, generate and store a password per student on your server.

graphql
mutation Signup($input: CreateUserInput!) {
  auth {
    createUser(input: $input) {
      success
      token
      expiresAt
      user {
        id
        email
        firstName
        lastName
      }
      errors {
        code
        field
        message
      }
    }
  }
}
json
{
  "input": {
    "email": "ava@example.com",
    "password": "correct-horse-battery",
    "firstName": "Ava",
    "lastName": "Nguyen"
  }
}

Store user.id, token, and expiresAt to authenticate subsequent requests. A successful registration signs the student in immediately. If the email is already registered under your domain, auth.createUser returns success: false with code: "EMAIL_ALREADY_EXISTS". Call auth.login instead.

Sign in ​

Tokens expire after 24 hours (expiresAt). Within 7 days of issuance, call auth.refreshToken with the existing Bearer <token> to get a new 24-hour token. After 7 days, or when you don't have a stored token, call auth.login.

graphql
mutation Login($input: LoginInput!) {
  auth {
    login(input: $input) {
      token
      expiresAt
      user {
        id
        email
      }
    }
  }
}
json
{
  "input": {
    "email": "ava@example.com",
    "password": "correct-horse-battery",
    "remember": true
  }
}

Update the profile ​

Owlflow uses the student's profile to determine scholarship eligibility and refreshes their matches whenever a profile field changes. For enum fields, send values from references.dictionaries rather than display text or postal codes (for example, "CALIFORNIA", not "CA").

graphql
mutation UpdateProfile($input: UpdateUserInput!) {
  viewer {
    updateUser(input: $input) {
      success
      user {
        firstName
        lastName
        dateOfBirth
        address {
          state
          zip
        }
        education {
          schoolLevel
          gpaOption
          degree
          degreeType
          collegeGraduationYear
        }
        citizenship
        careerGoal
      }
      errors {
        code
        field
        message
      }
    }
  }
}
json
{
  "input": {
    "firstName": "Ava",
    "lastName": "Nguyen",
    "dateOfBirth": "2007-04-12T00:00:00.000Z",
    "phone": "+14155550123",
    "citizenship": "US_CITIZEN",
    "careerGoal": "COMPUTERS_IT_TECHNOLOGY",
    "address": {
      "addressLine1": "1 Market St",
      "city": "San Francisco",
      "state": "CALIFORNIA",
      "zip": "94105"
    },
    "education": {
      "schoolLevel": "HIGH_SCHOOL_SENIOR",
      "degree": "COMPUTER_INFORMATION_SCIENCES",
      "degreeType": "BACHELORS",
      "gpaOption": "3.8",
      "collegeGraduationYear": 2031
    }
  }
}

gpaOption is one of the 4.0-scale GPA strings from references.dictionaries.gpas ("2.0" through "4.0", "4.1", or "N/A").

Set isEligible: true, isActive: true, and capBasedSortEnabled: true to return open scholarships that match the student's profile. Combine them with other filters to narrow the results. The search field searches scholarship content. Pass the previous pageInfo.endCursor as after to load the next page.

graphql
query Matches(
  $first: Int!
  $after: String
  $filters: ScholarshipFilters
) {
  scholarships {
    list(filters: $filters, pagination: { first: $first, after: $after }) {
      totalCount
      totalAmount
      pageInfo {
        hasNextPage
        endCursor
      }
      nodes {
        id
        title
        amount
        deadline
        isEasy
        requirementSummary {
          type
          count
          label
        }
      }
    }
  }
}
json
{
  "first": 20,
  "filters": {
    "isEligible": true,
    "isActive": true,
    "capBasedSortEnabled": true,
    "search": "engineering",
    "state": ["CALIFORNIA"],
    "schoolLevel": ["HIGH_SCHOOL_SENIOR"],
    "minAmount": 1000,
    "isEasy": true
  }
}

ScholarshipFilters also accepts deadlineBefore, degree, fieldOfStudy, maxRequirements, and requirementTypes with mode INCLUDE or EXCLUDE. Use isSaved: true for saved scholarships, isIgnored: true for ignored scholarships, and isSubmitted: true for submitted applications.

Apply ​

Load the scholarship's requirements with scholarships.byId, save each answer with scholarships.submitApplicationRequirementV2, and call scholarships.applyV2 once viewer.allMandatoryRequirementsCompleted is true. See Apply.

Owlflow partner API