{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"cb61ddcc-ab98-44af-ac48-ffb0aa1d6bde","name":"EverFi API","description":"The **Foundry external API** provides access for EVERFI's customers to retrieve and manage their data within the Foundry platform. The data returned by the API is essentially real-time.\n\nAPI location: `https://api.fifoundry.net`\n\nCurrent version: `v1`\n\n## API Authentication\n\nThe Foundry API requires every request to provide an authorization token, provided in a header property called `Authorization`. See the [Get Token](#6cb39f53-9809-4203-938e-0428da648da6) for details for how to get the token. When developing your API integration, you will need to implement a way to first authenticate your API, retrieve the `access_token` and `token_type` from a successful response, and then pass the `access_token` and `token type` to each subsequent request in the `Authorization` header property.\n\n### Token Management in Postman\n\nThis Postman Collection requires an accompanying Postman Environment called **EverFi Public API**. In that environment, you must set the `client_id` and `client_secret` variables for the Account you want to connect to.\n\nBefore running the various request templates in this collection, first run the [Get Token](#6cb39f53-9809-4203-938e-0428da648da6) request to update Environment variables for authorization that are used by the various requests. For convenience, all the other requests in this Collection use a Postman Environment variable named `access_token`.\n\nIn some of the requests, you may need to update a parameter's value.\n\n## API System Requirements\n\nThe system that connects to the Foundry API must be able to send and receive HTTP web requests and responses using the JSON format. Foundry observes the [JSON:API](https://jsonapi.org/) specification.\n\nAll integration traffic to the Foundry API must use TLS 1.2 (or higher) encryption. The API will only support the ciphers listed in the TLS-1-2 column on [this page](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies). Requests must be sent to the `https` endpoint, not `http`. The API will attempt to redirect any requests sent to the `http` URL to `https` instead, but do not rely on this. If your request does not allow redirects, then the API will respond with a `307`.\n\n### Cross-origin resource sharing (CORS)\n\nIf you are attempting to authenticate to the API in a browser, the browser may encounter errors relating to cross-origin resource sharing (CORS).\n\nThe API does not return headers that instruct a browser not to block an API request and allow cross domain requests. This is not a use case EVERFI supports because of security concerns about exposing API credentials publicly via browser traffic. Instead, EVERFI recommends API authentication be run server to server.\n\n## GET Request Filtering, Sorting and Fields List\n\nFor some API routes, you can specify an optional filter, sort order, and specify which fields you want in the response.\n\nBe aware that not every field can be a filter or sort, only certain ones. Generally, the documentation for each API route tells you which fields can be a filter or sort.\n\nThe integrator should always include a directive of which fields to return, since this will make the API run faster and return only needed data for a smaller response size.\n\n### Fields to return directive\n\nThe integrator should include only the fields needed in the response. Doing so will reduce the size and complexity of the response and return it to you faster.\n\nFor example:\n\n`https://api.fifoundry.net/v1/admin/users/?fields[users]=email,first_name,last_name,sso_id,employee_id,student_id,location_id,active,user_rule_set_roles,category_labels`\n\nYou can include fields that are part of a `relationships` such as `user_rule_set_roles` in the example above.\n\n### Filtering on Column Values\n\nWhen sending a GET request, some but not all fields permit a **filter**. For example, if you send a GET request to `admin/users`, you can filter on the user `location_id` like this so that only users at `1234` will be returned:\n\n`admin/users/?filter[location_id]=1234`\n\nYou can also send one request to filter on multiple values for the same field. The following request will return any users who have `location_id` that is either `1234` or `777`:\n\n`admin/users/?filter[location_id][]=1234&filter[location_id][]=777`\n\nOnly some fields in some API routes support filtering. See the documentation for each API route to know which fields may be a filter.\n\nTo filter on multiple fields, include as many filter fields as needed. The following request will return only users whose `last_name` is exactly \"Gutierrez\" AND who have either location_id `1234` or `777`:\n\n`admin/users/?filter[location_id][]=4297&filter[location_id][]=4972&filter[last_name]=Gutierrez`\n\nYou can filter only on the fields in the main resource; you cannot filter on data in resources that you `include`.\n\nImportant: You must URL encode any values that might have a special character, in particular email addresses.\n\n### Sorting Results\n\nIf desired, you may optionally sort the response on one or more fields, for example:\n\n`https://api.fifoundry.net/v1/admin/users/?sort=created_at`\n\nBy default, the sort order is ascending. To sort descending, put a `hyphen-minus` (`-`) in front of the field:\n\n`https://api.fifoundry.net/v1/admin/users/?sort=-created_at`\n\nTo sort on multiple fields, list then separated by a comma:\n\n`https://api.fifoundry.net/v1/admin/users/?sort=last_name,first_name,id`\n\nTo ensure consistent results, we recommend sorting on a field that is guaranteed to be unique. If you are not sure if your sort field is in fact unique, then try also including `id` in the column list.\n\n### Putting it all together\n\nThe following GET request exhibits all of these capabilities, and also includes the paging fields:\n\n`https://api.fifoundry.net/v1/admin/users/?page[number]=1&page[size]=100&fields[users]=email,first_name,last_name,sso_id,employee_id,student_id,location_id,active,user_rule_set_roles,category_labels&filter[location_id]=77&sort=created_at`\n\n## Set-Up Requirements and Recommendations\n\n**Information technology department**: This add-on service will require a certain level of technical expertise. An understanding of REST is assumed to best understand the technical requirements needed to implement this API. Introducing your information technology (IT) department to this effort early and inviting a representative to participate on your EVERFI team will ensure a more successful implementation.\n\n## API Rate Limit\n\nThe API limits an organization's APIs to at most 200 requests per rolling 60 seconds. If this limit is exceeded then you will get a `429` response code. Therefore, we recommend that your integration code be set up to handle a 429 response code and retry after an exponential \"back off\" pause. See our [best practices for managing 429 errors](https://help.everfi.com/s/article/api-response-error-429).\n\nBe aware that the rate limit is by organization, not by API. This means that if one organization has three different APIs, that all three of them count toward the rate limit. If a scenario should arise where one API is frequently hitting the rate limit even with a low request rate, then you will need to work with the organization to ensure each API gets its \"fair share\" of requests.\n\n## Supported Verbs\n\nEach route documents the supported verbs (POST, GET, PATCH, etc.) for the route. Sending a request with an unsupported verb will result in a `4XX` response that may differ for each route and scenario. Generally, Foundry does not respond with a `405` response for requests with an unsupported verb.\n\n## [Exceptions](#exceptions)\n\nIf your request is rejected by Foundry for violating a business rule, expect a `4XX` http status code and possibly an error message. For specifics, see the various _examples_ in the sample requests in this Postman Collection. Note that we are not able to include an example for every single conceivable error. For this reason, we recommend that you include handling for any sort of `4XX` or `5XX` error, and if desired you can include specific handling for certain `4XX` errors.\n\nIn general, you can retry a request that got a `5XX` error. Other than `429` rate limit errors, most other `4XX` errors will not succeed if you retry them.\n\nYou may want to log `4XX` errors and manually troubleshoot them after the fact. If desired, you can trap specific `4XX` errors and attempt to resolve them programatically, if there is a resolution.\n\n### Common `4XX` and `5XX` http status codes\n\nIn general, you can anticipate these as the most common client-fault http status codes. See **examples** for specific requests for more details. This is not an exhaustive list but a list of some of the more common ones.\n\n`400` - Bad Request - Foundry has various defenses against a generic bad request that could be considered invalid for many different reasons. If you get a `400` response, check the HTTP response text for guidance on the root cause. Be aware that while EVERFI staff can help you troubleshoot API issues by inspecting Foundry logs for incoming requests, these kinds of errors are not logged because they are blocked before entering Foundry's application zone. Therefore, you must inspect the raw HTTP response text to learn more.\n\n`403` - forbidden - sometimes a violation of a business rule might result in a `403` for example if you attempt to insert a user with a `rule_set` (aka \"line of business\") that your organization does not have. Sometimes a request may get this response code and an error message \"Public API access is not allowed\". While this message may seem wrong, it is often returned as a catch-all error message for responses where the caller lacks authorization to perform the operation on the resource; an example is trying to delete a user, which is not allowed.\n\n`404` - not found - if you try to PATCH or DELETE a record that doesn't exist, or attempt to write a resource with a property where its value doesn't exist (such as a user with an invalid `location_id`) then you may get a `404` response. Also expect a `404` if you send a GET by ID request with the ID in the URL path, and there is no record with that ID.\n\n`409` - conflict - often, this status code indicates that the schema of your request payload for a PATCH or POST is invalid. Foundry typically will not be able to tell you _why_ it is invalid, just that it _is_ invalid. Double check your formatting and JSON structure to make sure each property is in the right location, that you have double-quotes surrounding property names and values (unless the data type is a `number`), that you're formatting arrays properly with the brackets (`[` `]`) and braces (`{`, `}`) in the right places, etc. Make sure that the body has a single `data` property, is an `object` type, with properties for `type` (string) and `attributes` (object). If you're having trouble finding the specific problem, then you might want to take a correct body example from this collection and user it to generate a JSON schema with a tool like [JSON to JSON Schema Converter](https://www.liquid-technologies.com/online-json-to-schema-converter). Next, attempt to validate your own payload body against the generated schema at [JSON Validator (JSON Schema)<br>](https://www.liquid-technologies.com/online-json-schema-validator)and see if you can find the problem.\n\n`422` - unprocessable entry - you may get this status code for a logical violation of a business rule. Attempting to insert a new user whose email is a duplicate of another user, for example, will result in a `422`. You will get this error if you attempt to PATCH a resource but fail to provide the ID in the URL path.\n\n`429` - See \"API Rate Limit\" section above.\n\n`500` - similar to a `409`, if your payload schema is unrecognizable, you might see a `500` response. Normally, an invalid request body should respond with a `4XX` client fault, but in some cases if the body is unrecognizable, Foundry may not be able to handle it and respond with a `500`. Generally, Foundry strives to handle any invalid request with a `4XX` client fault, but in some cases Foundry fails to do so and therefore may respond with a generic `500`. If you get a `500`, we recommend a short pause and retry up to 3 attempts. If you continue to receive a `500` then do not keep retrying.\n\n### Uncommon exceptions\n\n`400` - Bad Request - Request Header Or Cookie Too Large - if you have a header property with a value that has too many characters (it could be 8,000 plus but may vary) then you might get this response. To resolve this, examine the HTTP headers you are sending (in particular the `Cookie` property) and reduce the size.\n\n`414` - Request-URI Too Large - you may get this response if you have a querystring value that has too many characters. It would be unusual to have a valid reason for doing this so examine your querystring and reduce the size of the query values.\n\n`503`, `504` - if you get one of these, pause and then retry up to several times.\n\n### Errors Object\n\nIn some cases, in the event of a `4XX` the response text will contain an array of objects that are called `errors`. For example, this is an error message from a request that included some invalid id values:\n\n```\n{\n    \"errors\": [\n        {\n            \"title\": \"Couldn't find all CategoryLabels with 'id': (3035, 3042) (found 0 results, but was looking for 2)\"\n        }\n    ]\n}\n\n ```\n\nIn some cases, in particular if there is a violation related to a specific property, the `error` object may contain additional properties describing the property. The property `field_name` specifies the property, along with the `message`, as shown below:\n\n```\n[\n    {\n        \"id\": \"user_rule_set\",\n        \"uid\": null,\n        \"errors\": [\n            {\n                \"field_name\": \"email\",\n                \"message\": \"user_09@example.com has already been taken\"\n            }\n        ]\n    }\n]\n\n ```\n\nIn some cases, the response may contain multiple elements in the `errors` array in the case of multiple violations:\n\n```\n[\n    {\n        \"id\": \"user_rule_set\",\n        \"uid\": null,\n        \"errors\": [\n            {\n                \"field_name\": \"email\",\n                \"message\": \"myemail@stateu.edu has already been taken\"\n            },\n            {\n                \"field_name\": \"sso_id\",\n                \"message\": \"myemail@example.com has already been taken for this organization\"\n            }\n        ]\n    }\n]\n\n ```\n\nBe aware that when Foundry validates a resource, in some cases it may validate every potential issue and then report back on every potential issue, or it may validate one condition at a time and throw an exception upon the first violation, without checking other potential violations. In the latter case, be prepared that even if you resolve the first violation and resend your request, that your second request may get rejected because of a different violation.\n\n### Inability to use PATCH verb\n\nQ. Our integration system cannot use the PATCH verb. We get an error message saying \"Invalid Method\" when sending a PATCH request to update a record. Do you have a suggestion on how to update records?\n\nA. Send a POST request instead, and in the header, add `X-HTTP-Method-Override:PATCH`. This is a way to semantically transform a POST request into a PATCH. Depending on your scenario, you may also be able to override to PUT.\n\n## Foundry API Certificate\n\nEVERFI uses a multi-domain SSL certificate for the API with the main domain being `platform.everfi.net`. The various domains within this certificate, such as `api.fifoundry.net`, are subject alternative names (SAN).\n\nIf you are experiencing certificate verification issues, we recommend verifying that your integration environments are up to date. We have observed that some older software versions might not correctly trust a certificate authority. If you continue to have issues, we recommend inquiring with your vendor.\n\n## Additional API Documentation\n\nSee the [Foundry customer knowledgebase](https://help.everfi.com/s/article/API-Integration) for longer best practices documentation on the API, while this website focuses more on detailed technical reference documentation.","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"3207949","team":76349,"collectionId":"cb61ddcc-ab98-44af-ac48-ffb0aa1d6bde","publishedId":"SVSDPrP7","public":true,"publicUrl":"https://documenter-api.postman.tech/view/3207949/SVSDPrP7","privateUrl":"https://go.postman.co/documentation/3207949-cb61ddcc-ab98-44af-ac48-ffb0aa1d6bde","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"EF5B25"},"documentationLayout":"classic-double-column","version":"8.10.0","publishDate":"2019-07-05T21:53:39.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{},"logos":{}},"statusCode":200},"environments":[{"name":"EverFi Public API - Startup","id":"81dc0ae3-8333-412f-ac12-30e3741b2234","owner":"3207949","values":[{"description":{"content":"","type":"text/plain"},"value":"","key":"client_id","enabled":true},{"description":{"content":"","type":"text/plain"},"value":"","key":"client_secret","enabled":true},{"description":{"content":"","type":"text/plain"},"value":"","key":"access_token","enabled":true},{"description":{"content":"","type":"text/plain"},"value":"","key":"scroll_id","enabled":true},{"description":{"content":"","type":"text/plain"},"value":"","key":"since","enabled":true},{"description":{"content":"","type":"text/plain"},"value":"https://api.fifoundry.net","key":"Endpoint","enabled":true},{"description":{"content":"","type":"text/plain"},"value":"v1","key":"Version","enabled":true}],"published":true}],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/3d3c460d59ce042f2d57d9165f53617b6e5aa68a0ba100a4f907013327dda2c6","favicon":""},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"},{"label":"EverFi Public API - Startup","value":"3207949-81dc0ae3-8333-412f-ac12-30e3741b2234"}],"canonicalUrl":"https://documenter.gw.postman.com/view/metadata/SVSDPrP7"}