Appearance
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.
| Environment | Endpoint |
|---|---|
| Staging | https://owlflow.scholarshipowl.tech/graphql |
| Production | https://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").
Search
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.
