Unlike REST APIs, GraphQL servers don’t use HTTP status codes to indicate unsuccessful requests.
Instead, the GraphQL response body includes an array of If you receive an A A An Your software should have a reasonable retry policy on
errors
when an operation fails.The SEEK API uses four error codes to classify the type of error that occurred.
Depending on the type of error there will be further information in the error’s message
and extensions
.The SEEK API’s error messages are safe to expose to SEEK hirers.
However, some errors responses can indicate a problem with your SEEK API integration that’s not actionable by an end user.
If you decide to hide those error messages, your software should still log the full message to support debugging issues.An UNAUTHENTICATED
error indicates a problem with the access token included in the request.
More details will be available in the error’s message
.- An access token wasn’t included in the request’s
Authorization
header. - The access token has expired. This can happen if the access token is used after the
expires_in
from the token response. - A Playground access token was used to access live data or vice versa.
JSON
Copy
{
"errors": [
{
"message": "Public test partner token is expired",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": ["candidateProfile"],
"extensions": {
"code": "UNAUTHENTICATED"
}
}
]
}
UNAUTHENTICATED
error due to an expired access token as per the example above,
your software may request a new access token and use it to automatically retry the request.
Limit such behaviour to a single retry;
if your software continues to receive the same error with a newly issued token then you have likely misconfigured the request and further retries will not help.You may be able to customise your GraphQL or HTTP client library to implement a retry policy.
Ensure that your retry policy takes the error code in the response into account,
as retrying a request with a different error like FORBIDDEN
is unlikely to produce a different result.A FORBIDDEN
error indicates a valid access token was received but there was a problem authorizing the operation.
More details will be available in the error’s message
.It’s possible to have access to an object but not all of its nested objects or fields.
For example, you can query a PositionProfile
for Optimised Apply but wouldn’t be able to query its branding
without an additional JobPosting
relationship.
To help debugging these situations the error’s path
will indicate which field encountered the FORBIDDEN
error.Requests that fail authorization should not be automatically retried.- SEEK has not configured a relationship between you and the SEEK hirer.You can view a list of your SEEK hirers and their relationships on the Developer Dashboard’s hirers page.
- The SEEK hirer’s account has been disabled.
- A browser token was used without the scope required for the operation.
- You used a mutation against Playground data.The Playground returns
FORBIDDEN
errors after validating the mutation’s input. You can use this feature to test input validation in the Playground environment.
query ($id: String!) {
# Hirer has been disabled
hiringOrganization(id: $id) {
name
}
}
BAD_USER_INPUT
error indicates the operation failed input validation.
A top-level summary of the validation failure will be available in the error’s message
.Some operations support additional field-level messages in the invalidFields
map.
Its keys are JSON Pointers to the invalid fields in the operation’s arguments.
These map to a message describing why the field failed validation.Requests that fail validation should not be automatically retried.- The input was the correct type for the GraphQL schema but violated a more specific constraint.
- A mutation’s input referenced an object that doesn’t exist.
- The operation exceeded the SEEK API’s query complexity limit.An operation’s complexity is calculated based on the estimated size of its response. Overly complex operations are rejected before they’re executed to prevent denial of service attacks .
mutation ($input: CreateWebhookSubscriptionInput!) {
createWebhookSubscription(input: $input) {
... on CreateWebhookSubscriptionPayload_Success {
webhookSubscription {
id {
value
}
}
}
... on CreateWebhookSubscriptionPayload_Conflict {
conflictingWebhookSubscription {
id {
value
}
}
}
}
}
RATE_LIMITED
error indicates that the request has been blocked due to a rate limit being exceeded.
To maintain system stability, the SEEK API rate limits requests that significantly exceed typical usage patterns.Rate limits are applied per query/mutation and may vary depending on the specific operation being performed.
Certain queries and mutations may have their rate limits documented in the SEEK API schema when appropriate, however most limits are generous but undocumented, and subject to change.- Uncontrolled loops: If SEEK API requests are made in a loop, take care to ensure the loop terminates appropriately. An uncontrolled loop could cause your software to call the SEEK API in an infinite loop, quickly exceeding your request quota.
- Excessive retries: Retrying failed requests too aggressively could cause your software to consume its request quota quickly.
JSON
Copy
{
"errors": [
{
"message": "Too many requests. Contact SEEK for assistance.",
"path": ["postPosition"],
"extensions": {
"code": "RATE_LIMITED"
}
}
]
}
INTERNAL_SERVER_ERROR
indicates an unexpected failure occurred while processing the request.Error details are omitted from the response to avoid exposing sensitive information about SEEK’s systems.
However, the message will contain a reference code SEEK can use to find more details in our internal logs.JSON
Copy
{
"errors": [
{
"message": "Oops. Something went wrong. If you continue to experience issues, contact support and quote error reference '112c-4edf-af8e'.",
"path": ["positionProfile"],
"extensions": {
"code": "INTERNAL_SERVER_ERROR"
}
}
]
}
INTERNAL_SERVER_ERROR
errors for robustness .
This increases the likelihood that your integration will remain operational through transient failures in the SEEK API.
You may also time out and retry a request if it has taken too long for the SEEK API to respond.Requests that carry a mutation must be idempotent to prevent retries from unintentionally creating or modifying multiple objects.
For example, you must use the same idempotencyId
when retrying a job posting mutation to ensure that only one job ad is created.You may be able to customise your GraphQL or HTTP client library to implement a retry policy.
Ensure that your retry policy takes the error code in the response into account,
as retrying a request with a different error like FORBIDDEN
is unlikely to produce a different result.The policy behaviour may differ based on the use case.
A shorter request timeout and backoff may be appropriate a high-volume interactive hirer experience like location suggest.
On the other hand,
a back-end process like exporting applications could have a longer delay between retries and send persistent failures to a dead letter queue for manual reprocessing once the SEEK API has restored service.Your software should cap the number of request retries and implement exponential backoff and jitter as best practices.
By progressively increasing the delay between retries and introducing a random factor to the calculation,
you space out your requests and avoid overwhelming the SEEK API, increasing the likelihood that your requests will be served sooner.
Generally speaking, you should not retry a request more than 3 times.Contact SEEK if you need to discuss the specifics of your retry policy.The GraphQL error codes above accompany a HTTP status code of 200
.
However, the SEEK API may return HTTP status codes other than 200
in some scenarios.If you encounter any of these and need assistance, contact SEEK’s support team with details such as your tracing headers, the request body, as well as the status code, headers and body of the response.HTTP response status codes other than 200
may include:400
, alongside aGRAPHQL_PARSE_FAILED
orGRAPHQL_VALIDATION_FAILED
GraphQL error codes. These error codes indicate a problem with GraphQL syntax or schema usage with your software, and generally should only occur during development.400
or403
codes may be returned if security controls are triggered. In this scenario, the response body might not be JSON.- A
429
status code may be returned by attachment download endpoints if the request rate exceeds the allowed limit. 500
,502
,503
and other5xx
codes may indicate the SEEK API is experiencing an outage or other technical issue. You can check the status page for any known issues. In this scenario, the response body might not be JSON. Your software should implement a retry policy for these errors.- Networking errors may surface in different forms depending on your technology stack. For example, connection timeouts, socket timeouts, socket hangups, or otherwise. This could indicate a problem in the SEEK API, your networking, or anything in between. You can check the status page for any known issues. Your software should implement a retry policy for these errors.