Ed-Fi ODS-API Error Responses

Background

The Ed-Fi ODS/API follows REST principles in responding to HTTP requests, including use of standard status codes in the HTTP response:

  • 2xx codes for "good" situations (e.g. 200 "ok", 201 "created", etc.),
  • 4xx codes for "bad" requests that the API client can modify and try again (e.g. 400 "bad request"), and
  • 5xx codes for "bad" requests that occur on the server due to a software bug, unexpected situation, or upstream connectivity problems (e.g. 500 "internal server error").

Applying the standard HTTP response codes appropriately is a good step toward standardization: a client receiving a 400 will know that the request body is malformed or the data are not valid. 

But how does the application know precisely what went wrong? Typically, a 4xx error response will include a human readable message that describes the problem in more detail. These messages are not standardized, and it can be difficult to standardize* across multiple implementation surfaces. This document attempts to catalog most of the error responses coming from the Ed-Fi ODS/API, along with additional notes, where applicable, that may help an application developer know more about how to handle the situation. This document may be useful both for further standardization efforts, and for those who are building client applications that will need to consume the error messages.

Why is message standardization so hard?

There are many validation frameworks for checking the request body for conformance with the expected shape and data types, and they all have their own response terminology. Even within the ODS/API application there can be variations on the human readable message, because it relies heavily on the backend relational database technology to generate messages about data type and referential integrity errors. Which message text should be the canonical version (if any)? And who is going to write the translation from one format to the other?

Each example below provides a brief description of the problem, a sample HTTP request, and a comment about how to resolve. Broadly speaking, there are three possibilities for error resolution:

  1. The problem may exist in application code → send to the application development team for resolution.
  2. It could be on the hosting side → report to the hosting provider / IT Operations team for resolution.
  3. Missing or invalid source system data → report to an appropriate application user to correct the data and resubmit.

Table of Contents

Status Code 400 Bad Request

POSTing a Request with Resource ID

A POST request should not contain an id  value. This value is auto-assigned by the API application.

Example:

## HTTP Request

POST https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors
Authorization: bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json

{
  "id": "a49a738b92b74a94a91ac7fa3bb19b15",
  "absenceEventCategoryDescriptorId": 1,
  "codeValue": "Bereavement",
  "description": "Bereavement",
  "namespace": "uri://ed-fi.org/AbsenceEventCategoryDescriptor",
  "shortDescription": "Bereavement"
}

## HTTP Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "message": "Resource identifiers cannot be assigned by the client."
}

Interestingly, in the example above, abscenEventCategoryDescriptorId is simply ignored. This is peculiar to the Descriptor API in the ODS/API application, as other Resources do not expose a numeric identifier like this.

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Remove the id  value from the payload when POSTing a request.
  • However, please note that the id  value is required when issuing a PUT request. This is because a PUT request is intended to represent the complete definition of the stored resource.

Missing a Required Property

The data model for every endpoint includes one or more required property / field.

Example: missing one required property, codeValue.

## HTTP Request

POST https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors
Authorization: bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json

{
  "description": "Bereavement",
  "namespace": "uri://ed-fi.org/AbsenceEventCategoryDescriptor",
  "shortDescription": "Bereavement"
}

## HTTP Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "message": "Validation of 'AbsenceEventCategoryDescriptor' failed.\r\n\tCodeValue is required.\n"
}

Example: missing two required properties, codeValue  and shortDescription:

## HTTP Request

POST https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors
Authorization: bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json

{
  "description": "Bereavement",
  "namespace": "uri://ed-fi.org/AbsenceEventCategoryDescriptor"
}

## HTTP Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "message": "Validation of 'AbsenceEventCategoryDescriptor' failed.\r\n\tCodeValue is required.\n\tShortDescription is required.\n"
}

Example: the required property exists in the payload, but it is set to null  or an empty string:

## HTTP Request

POST https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors
Authorization: bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json

{
  "codeValue": "",
  "description": "Bereavement",
  "namespace": "uri://ed-fi.org/AbsenceEventCategoryDescriptor",
  "shortDescription": "Bereavement"
}

## HTTP Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "message": "Validation of 'AbsenceEventCategoryDescriptor' failed.\r\n\tCodeValue is required.\n"
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Review the Swagger UI documentation to find all required fields.
  • Each data model is available in a collection at the bottom of the page, or you can expand the various HTTP requests and find the model embedded within it. Example:
  • Make sure that a value is being transmitted for the property - not an empty string or null.

Example: missing namespace . For Descriptors, this is a special case that results in 403. See Missing Namespace for Descriptors below.

String Length Validation Error

The Ed-Fi Data Model prescribes a maximum string length in many cases. The application code needs to truncate strings to fit, if they are larger than the data model's allowed length.

## HTTP Request

POST https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors
Authorization: bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json

{
  "codeValue": "Bereavementddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",     
  "shortDescription": "Bereavement",
  "namespace": "uri://ed-fi.org/AbsenceEventCategoryDescriptor"
}

## HTTP Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "message": "Validation of 'AbsenceEventCategoryDescriptor' failed.\r\n\tThe field CodeValue must be a string with a maximum length of 50.\n"
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • The error message is specific enough to resolve the problem in code.

If an immediate application update is not possible, the problem can potentially be sent to an application user to manually shorten the string from within the source system, before retrying the data synchronization process.

Student Does Not Exist in StudentSchoolAssociations

This is an edge case - most referential integrity errors receive a 409 response, not a 400 response.

## HTTP Request

POST https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors
Authorization: bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json

{
  "classOfSchoolYearTypeReference": {
    "schoolYear": 2027
  },
  "schoolReference": {
    "schoolId": 338978318
  },
  "studentReference": {
    "studentUniqueId": "i don't exist"
  },
  "entryDate": "1903-03-18",
  "entryGradeLevelDescriptor": "uri://ed-fi.org/GradeLevelDescriptor#First grade",
  "entryTypeDescriptor": "uri://ed-fi.org/EntryTypeDescriptor#Next year school",
  "residencyStatusDescriptor": "uri://ed-fi.org/ResidencyStatusDescriptor#Resident of admin unit and school area"
}

## HTTP Response

HTTP/1.1 400 Bad Request
Content-Type application/json; charset=utf-8

{
  "message": "Validation of 'StudentSchoolAssociation' failed.\r\n\tStudent reference could not be resolved.\n"
}

## or, some systems may strip out the line ending and tab characters {\r, \n, \t} when writing to a log:

{
  "message": "Validation of 'StudentSchoolAssociation' failed. Student reference could not be resolved."
}

How to Resolve

Problem might be in the application code → send to application development team for resolution.

Alternately, the code might be correct, and there could be an "upstream" problem → send for application user review.

  • Was there an error when synchronizing the upstream resource, such that it did not save correctly? In the above example, look to see if there was an error when creating the Student. If so, might need to correct something on one or more Student records in order to complete the Student synchronization and then re-try the StudentSchoolAssociation synchronization.

Unable to Delete an Item Due to Upstream Dependency

When resource A depends on resource B, you cannot delete an instance of resource B without first deleting all resource A instances that depend on that to-be-deleted instance of B. Translation: cannot delete a parent record when there are child records still.

## HTTP Request

DELETE https://api.ed-fi.org:443/v6.1/api/data/v3/ed-fi/students/3d3ad42503b443489471b74c05067628
Authorization: Bearer 6f5bb488a65948b5b847b561b23e

## HTTP Response

HTTP/1.1 409 Conflict Content-Type: application/json; charset=utf-8

{
  "message": "The resource (or a subordinate entity of the resource) cannot be deleted because it is a dependency of the 'studentUSI' value of the 'studentAcademicRecord' entity."
}

How to Resolve

Problem might be in the application code → send to application development team for resolution.

  • Be sure to delete data following the required Resource Dependency Order in reverse order (delete children first).
  • This specific case may have arisen because a Student Unique ID changed. This value is a natural key that is cannot be updated via a PUT request (see Cascading Key Updates on ODS / API Resources for those natural keys that can be updated via a PUT request). Because of this, the student record needs to be deleted and resubmitted if there is a correction to the Student Unique Id.

Descriptor Does Not Exist

This error occurs when the HTTP request structure is good, but one or more descriptor value does not exist.

Example: bad descriptor codeValue

## HTTP Request

PUT https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/studentAcademicRecords/d074a26cec7449299f701ba54e0f0257
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-8

{
  "id": "d074a26cec7449299f701ba54e0f0257",
  "educationOrganizationReference": {
    "educationOrganizationId": 255901001
  },
  "schoolYearTypeReference": {
    "schoolYear": 2022
  },
  "studentReference": {
    "studentUniqueId": "604874"
  },
  "termDescriptor": "uri://ed-fi.org/TermDescriptor#Summer Semester33",
  "gradePointAverages": [
    {
      "gradePointAverageTypeDescriptor": "uri://ed-fi.org/GradePointAverageTypeDescriptor#Unweighted",
      "gradePointAverageValue": 4,
      "isCumulative": true
    }
  ]
}

## HTTP Response

HTTP/1.1 409 Conflict
Content-Type: application/json; charset=utf-8

{
  "message": "Unable to resolve value 'uri://ed-fi.org/TermDescriptor#Summer Semester33' to an existing 'TermDescriptor' resource."
}

Example: bad descriptor

## HTTP Request

PUT https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/studentAcademicRecords/d074a26cec7449299f701ba54e0f0257
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-8

{
  "id": "d074a26cec7449299f701ba54e0f0257",
  "educationOrganizationReference": {
    "educationOrganizationId": 255901001
  },
  "schoolYearTypeReference": {
    "schoolYear": 2022
  },
  "studentReference": {
    "studentUniqueId": "604874"
  },
  "termDescriptor": "uri://ed-fi.org/TermDescriptor___#Fall Semester",
  "gradePointAverages": [
    {
      "gradePointAverageTypeDescriptor": "uri://ed-fi.org/GradePointAverageTypeDescriptor#Unweighted",
      "gradePointAverageValue": 4,
      "isCumulative": true
    }
  ]
}

## HTTP Response

HTTP/1.1 409 Conflict Content-Type: application/json; charset=utf-8

{
  "message": "Unable to resolve value 'uri://ed-fi.org/TermDescriptor___#Fall Semester' to an existing 'TermDescriptor' resource."
}

Example 3: bad namespace

## HTTP Request

PUT https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/studentAcademicRecords/d074a26cec7449299f701ba54e0f0257
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-8

{
  "id": "d074a26cec7449299f701ba54e0f0257",
  "educationOrganizationReference": {
    "educationOrganizationId": 255901001
  },
  "schoolYearTypeReference": {
    "schoolYear": 2022
  },
  "studentReference": {
    "studentUniqueId": "604874"
  },
  "termDescriptor": "uri://wrong.org/TermDescriptor#Fall Semester",
  "gradePointAverages": [
    {
      "gradePointAverageTypeDescriptor": "uri://ed-fi.org/GradePointAverageTypeDescriptor#Unweighted",
      "gradePointAverageValue": 4,
      "isCumulative": true
    }
  ]
}

## HTTP Response

HTTP/1.1 409 Conflict
Content-Type: application/json; charset=utf-8

{
  "message": "Unable to resolve value 'uri://wrong.org/TermDescriptor#Fall Semester' to an existing 'TermDescriptor' resource."
}

How to Resolve

The problem could be in either the application code or in the source system, depending on how descriptor values are mapped: most systems will have a mapping from their own code set to Ed-Fi descriptors, but there may be special cases where an application user is manually entering a value into the source system user interface.

  • Review how the descriptor value is created in the synchronization process - is it in code or in the user interface?
  • Forward the problem to the appropriate group: application development team, or source system users.

Note that the error message contains the unknown value:

  • Example one: "Summer Semester33" is not a valid codeValue 
  • Example two: "TermDescriptor___" is not a valid Descriptor.
  • Example three: "wrong.org" in the base URI should be "ed-fi.org"

Non-Compliant JSON Body

What happens if the JSON body on a POST or PUT request is not valid? Generally, you get a detailed message telling you exactly where to look for the error.

Example: an extra comma after the schoolId value. One trailing comma is fine, but two is an error.

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/academicWeeks
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-8

{
  "weekIdentifier": "one",
  "schoolReference": {
    "schoolId": 17012391,,
  },
  "beginDate": "2023-09-11",
  "endDate": "2023-09-11"
}

## HTTP Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "message": "The request is invalid.",
  "modelState": {
    "request.schoolReference.schoolId": [
      "Invalid property identifier character: ,. Path 'schoolReference.schoolId', line 4, position 25."
    ],
    "request.schoolReference.schoolId.schoolReference": [
      "Invalid property identifier character: ,. Path 'schoolReference.schoolId', line 4, position 25."
    ]
  }
}

Example: missing closing curly brace before beginDate.

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/academicWeeks
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-8

{
  "weekIdentifier": "one",
  "schoolReference": {
    "schoolId": 17012391,

  "beginDate": "2023-09-11",
  "endDate": "2023-09-11"
}

## HTTP Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "message": "The request is invalid.",
  "modelState": {
    "request.schoolReference": [
      "Unexpected end when deserializing object. Path 'schoolReference', line 8, position 1."
    ]
  }
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Review the code for building the JSON payload.
  • Ideally use an object serializer rather building JSON by hand. 

Integer Overflow

Most integers in an Ed-Fi API resource are Int32 (max value: 2,147,483,647), though a few may be Int64 starting with ODS/API 7.0 (max value:9,223,372,036,854,775,807). Here's what happens in the ODS/API when you enter a number whose absolute value is too large:

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/chartOfAccounts
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-8

{
  "educationOrganizationReference": {
    "educationOrganizationId": 255901111111
  },
  "fundDimensionReference": {
    "code": "1",
    "fiscalYear": 4022
  },
  "accountIdentifier": "1-1-1000-000",
  "fiscalYear": 2022,
  "accountName": "TOTAL REVENUE FROM LOCAL SOURCES",
  "accountTypeDescriptor": "uri://ed-fi.org/AccountTypeDescriptor#Revenue"
}

## HTTP Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "message": "The request is invalid.",
  "modelState": {
    "request.educationOrganizationReference.educationOrganizationId": [
      "JSON integer 255901111111 is too large or small for an Int32. Path 'educationOrganizationReference.educationOrganizationId', line 3, position 45."
    ]
  }
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • It is conceivable that a source system might have an Int64 where the Ed-Fi API only supports an Int32. In that case, the system will need to create and record a new Int32 value, alongside the existing Int64 value, just for transmission to the Ed-Fi API.

Excessive String Length

Many properties that take a string value have a maximum length associated with them. For example, rating  on accountabilityRatings has a max length of 35 characters.

## HTTP Request

POST https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/accountabilityRatings
Authorization: bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json

{
  "educationOrganizationReference": {
    "educationOrganizationId": 255901
  },
  "schoolYearTypeReference": {
    "schoolYear": 2014
  },
  "ratingTitle": "0eo0nvikbcrieawaybmhipgao8sjnxgl",
  "rating": "This has more than 35 characters in it"
}

## HTTP Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "message": "Validation of 'AccountabilityRating' failed.\r\n\tThe field Rating must be a string with a maximum length of 35.\n"
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Review the detailed error message, which includes the max length value and which field it applies to.
  • For proactive analysis, review the Swagger UI documentation to find other maximum string lengths.
  • Each data model is available in a collection at the bottom of the page, or you can expand the various HTTP requests and find the model embedded within it. Example:

Empty Request Object

What happens when you send a JSON object that contains no properties? You get an error that the required natural key property(ies) does not exist.

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/schools
Authorization: Bearer 6f5bb488a65948b5b847b561b23e 
Content-Type: application/json; charset=utf-8

{
}

## HTTP Response

HTTP/1.1 400 Bad Request 
Content-Type: application/json; charset=utf-8

{
  "message": "Value for resource's identifier property 'EducationOrganizationId' is required."
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Ensure that a non-empty payload is being transmitted.
  • Ensure that all required properties are included in that payload.

In this specific case the message is unfortunately a bit misleading, since School has a schoolId property, not a educationOrganizationId property.

Empty Request Body

In the previous example, the request does have a body, it just doesn't have any properties in it. What happens if you don't send a body at all?

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/schools
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-8

## HTTP Response

HTTP/1.1 400 Bad Request 
Content-Type: application/json; charset=utf-8

{
  "message": "A non-empty request body is required."
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Ensure that a JSON payload is generated and attached to the POST or PUT command.

Transmitting in the Wrong Character Encoding

The Ed-Fi ODS/API expects UTF-8 character encoding. In the following example, the content-type  is set as UTF-16, but the content is actually in UTF-8.

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/schools
Authorization: Bearer 6f5bb488a65948b5b847b561b23e 
Content-Type: application/json; charset=utf-16

{
  "educationOrganizationReference": {
    "educationOrganizationId": 255901
  },
  "schoolYearTypeReference": {
    "schoolYear": 2014
  },
  "ratingTitle": "0eo0nvikbcrieawaybmhipgao8sjnxgl",
  "rating": "rating"
}

## HTTP Response

HTTP/1.1 400 Bad Request 
Content-Type: application/json; charset=utf-8

{
  "message": "Unexpected character encountered while parsing value: ൻ. Path '', line 0, position 0."
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Make sure the content-type  is UTF-8, not anything else.

Potentially Dangerous Value

Un-escaped HTML will be rejected in the validation process, as a protection for avoiding potential cross-site scripting attacks against other applications that consume data from the Ed-Fi ODS/API.

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/schools
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-16


{
  "educationOrganizationReference": {
    "educationOrganizationId": 255901
  },
  "schoolYearTypeReference": {
    "schoolYear": 2014
  },
  "ratingTitle": "0eo0nvikbcrieawaybmhipgao8sjnxgl",
  "rating": "<script>alert('hello world!')</script>"
}

## HTTP Response

HTTP/1.1 400 Bad Request 
Content-Type: application/json; charset=utf-8

{
  "message": "Validation of 'AccountabilityRating' failed.\r\n\tThe field Rating must be a string with a maximum length of 35.\n\tRating contains a potentially dangerous value.\n"
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Encode the < character as &lt;

    "rating": "&lt;script>alert('hi')&lt;/script>"

Also, it might be good to take this up with your internal security team, as this may mean that a source system user is trying to perform a malicious injection attack on your application.

Leading or Trailing Whitespace in Natural Key String

Strings that compose the natural key on a resource cannot have a space in the initial or last position of the string.

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/accountabilityRatings
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-16


{
  "educationOrganizationReference": {
    "educationOrganizationId": 255901
  },
  "schoolYearTypeReference": {
    "schoolYear": 2014
  },
  "ratingTitle": " rating title ",
  "rating": "rating9"
}

## HTTP Response

HTTP/1.1 400 Bad Request 
Content-Type: application/json; charset=utf-8

{
  "message": "Validation of 'AccountabilityRating' failed.\r\n\tRatingTitle property is part of the primary key and therefore its value cannot contain leading or trailing whitespace.\n"
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • If the source system allows this, then strip spaces from the front or back of the string.

No Item in Required Array

Some resources have required arrays / collections on them. The error message is specific to the circumstance of an empty array in the JSON payload.

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/bellSchedules
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-16

{
  "bellScheduleName": "one",
  "classPeriods": [],
  "schoolReference": {
    "schoolId": 255901
  }
}

## HTTP Response

HTTP/1.1 400 Bad Request 
Content-Type: application/json; charset=utf-8

{
  "message": "Validation of 'BellSchedule' failed.\r\n\tBellScheduleClassPeriods requires at least one object in the collection.\n"
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Review the model definition and ensure that you only synchronize objects (bell schedules, in this case) when they can resolve a collection.

There is also a potential source system fix, where the source system has the same concept but does not require that the collection / array be populated. In that case, it might still be beneficial to write the synchronization code so that it ignores such records, rather than making a source system user go in and enter some value that would not normally be applicable.

Missing a Required Property on an Item in a Collection

Some resources have collections (arrays) of information, and the model for that collection may include required fields. The error message will help guide you not only to the field, but also which entry in the collection has the problem.

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/assessments
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-16

{
  "assessmentIdentifier": "_01774fa3-06f1-47fe-8801-c8b1e65057f3_",
  "namespace": "uri://example.com/Assessment/Assessment.xml",
  "assessmentCategoryDescriptor": "uri://ed-fi.org/AssessmentCategoryDescriptor#Benchmark test",
  "assessmentTitle": "3rd Grade Reading 1st Six Weeks 2021-2022",
  "academicSubjects": [
    {
      "academicSubjectDescriptor": "uri://ed-fi.org/AcademicSubjectDescriptor#English Language Arts"
    }
  ],
  "identificationCodes": [
    {
      "assessmentIdentificationSystemDescriptor": "uri://ed-fi.org/AssessmentIdentificationSystemDescriptor#Test Contractor",
      "identificationCode":  "01774fa3-06f1-47fe-8801-c8b1e65057f3"
    }
  ],
  "scores": [
    {
      "assessmentReportingMethodDescriptor": "uri://ed-fi.org/AssessmentReportingMethodDescriptor#Percentile",
      "maximumScore": "99",
      "minimumScore": "1",
      "resultDatatypeTypeDescriptor": "uri://ed-fi.org/ResultDatatypeTypeDescriptor#Integer"
    },
    {
      "_assessmentReportingMethodDescriptor": "uri://ed-fi.org/AssessmentReportingMethodDescriptor#Percentile",
      "maximumScore": "10",
      "minimumScore": "0",
      "resultDatatypeTypeDescriptor": "uri://ed-fi.org/ResultDatatypeTypeDescriptor#Integer"
    }
  ],
}

## HTTP Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "message": "Validation of 'Assessment' failed.\n\tValidation of 'AssessmentScores' failed.\n\t\tAssessmentScore[1]: AssessmentReportingMethodDescriptorId is required.\n"
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Review the model definition.
  • The error message points to item [1] ;  in zero-based indexing, that is the second entry. Note that there is a "typo" with an underscore at the beginning of the assessmentReportingMethodDescriptor  key.

Key Unification Error

Due to the Key Structure in the Ed-Fi ODS / API, a single resource may contain a certain property, and it may reference another object that has that same property. Often, the two values should be the same for consistency. We call this "key unification". The example below has some interesting features:

  • The school year and school Id at the root of the object should match those values found in the calendar reference (example of unification)
  • There is also "class of" school year - naturally, this will be different, since it represents the expected graduation date of the student.
  • Finally, there is a graduation plan that also has a school year. Typically one would expect that the graduation plan year would match the class of school year - but conceivably these may differ at times. A student might nominally be in a particular class, but planning on graduating early.
## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/studentSchoolAssociations
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-16

{
  "schoolYearTypeReference": {
     "schoolYear": 2023
   },
  "calendarReference": {
    "calendarCode": "2010605675",
    "schoolYear": 2022,
    "schoolId": 255901107
  },
  "classOfSchoolYearTypeReference": {
    "schoolYear": 2027
  },
  "schoolReference": {
    "schoolId": 338978318
  },
  "studentReference": {
    "studentUniqueId": "8y0mfuzfnffmdk00sgizqy5sj80kvanm"
  },
  "entryDate": "2023-03-18",
  "entryGradeLevelDescriptor": "uri://ed-fi.org/GradeLevelDescriptor#First grade",
  "graduationPlanReference": {
    "educationOrganizationId": 17012391,
    "graduationPlanTypeDescriptor": "uri://ed-fi.org/GraduationPlanTypeDescriptor#Standard",
    "graduationSchoolYear": 2020
  }
}

## HTTP Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8

{
  "message": "Validation of 'StudentSchoolAssociationPost' failed.\n\tSupplied values for unified key property 'schoolId' on 'StudentSchoolAssociation' are not consistent: schoolReference.schoolId = 338978318, calendarReference.schoolId = 255901107\n\tSupplied values for unified key property 'schoolYear' on 'StudentSchoolAssociation' are not consistent: calendarReference.schoolYear = 2022, schoolYearTypeReference.schoolYear = 2023\n"
}

How to Resolve

Problem may be in the application code → send to application development team for resolution.

  • Review the model definition.
  • Ensure that the right values are being transmitted.

However, this conceivably might be a source system problem that requires modification by an end user, if the source system itself allows for selecting a combination of values that are logically inconsistent in this way.

Invalid Limit Count

Client applications issuing GET requests, with or without search terms, can control how many records come back from a request - up to a maximum count. By default that max count is 500. 

## HTTP Request

GET https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/studentSchoolAssociations?limit=501
Authorization: Bearer 6f5bb488a65948b5b847b561b23e

## HTTP Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8  

{
    "message": "Limit must be omitted or set to a value between 1 and max value defined in configuration file (defaultPageSizeLimit)."
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Change the limit to be no more than 500.
  • Reach out to the hosting provider if 500 still generates this error, to find out what lower limit they have set.

Status Code 401 Unauthorized

There are several reasons why status code 401 may be returned. For enhanced security, the application does not provide detailed information about the reason. The 401 response may be for any of these reasons:

  • Missing Authorization  header
  • Invalid Authorization  header (for example, missing the word "bearer", or leaving the out the access token)
  • Expired access token
## HTTP Request

POST https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors
Authorization: bearer 6f5bb488a65948b5b847b561b23e 
Content-Type: application/json

{
  "description": "Bereavement",
  "namespace": "uri://ed-fi.org/AbsenceEventCategoryDescriptor"
}

## HTTP Response

HTTP/1.1 401 Unauthorized Content-Type: application/json; charset=utf-8

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Did the token time out? If so, re-authenticate with client credentials.
    • The token timeout period defaults to 30 minutes, but that value can be modified by the application host.
  • Inspect the HTTP request to ensure it is well formatted. 

For more information authentication and authorization in ODS/API 6.1, see Authentication and Authorization. This guidance is generally correct for all supported versions of the ODS/API.

Status Code 403 Forbidden

Missing Namespace for Descriptors

All Descriptors have a namespace, which is used by the Ed-Fi API to help secure data. When that value is missing or the value does not match the namespace configured for the client credentials, then the request will not be allowed to proceed.

Example: missing namespace

## HTTP Request

POST https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors
Authorization: bearer 6f5bb488a65948b5b847b561b23e 
Content-Type: application/json

{
  "codeValue": "Bereavement",
  "shortDescription": "Bereavement",
  "description": "Bereavement"
}  ## HTTP Response

HTTP/1.1 403 Bad Request Content-Type: application/json; charset=utf-8

{
  "message": "Access to the resource item could not be authorized because the Namespace of the resource is empty."
}

Example: invalid namespace

## HTTP Request

POST https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors 
Authorization: bearer 6f5bb488a65948b5b847b561b23e 
Content-Type: application/json

{
  "codeValue": "Bereavement",
  "shortDescription": "Bereavement",
  "description": "Bereavement"
}

## HTTP Response

HTTP/1.1 403 Bad Request 
Content-Type: application/json; charset=utf-8 

{
  "message": "Access to the resource item could not be authorized based on the caller's NamespacePrefix claims: 'uri://ed-fi.org', 'uri://gbisd.org', 'uri://tpdm.ed-fi.org'."
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Ensure that the namespace  is populated.
  • If it is populated but incorrect, then review the detailed error message to see what namespace prefixes are allowed for the given client credentials (e.g "uri://ed-fi.org", "uri://gbisd.org", or "uri://tpdm.ed-fi.org" in the example above.

Student / Parent / Staff Relationship Does Not Exist

This frequently trips up folks new to working with the Ed-Fi API: once you create a student, parent, or staff, most* client credentials cannot immediately access that record (* depending on the claimset configured for those client credentials). In order to access, there must be a relationship expressed as an  appropriate studentSchoolAssociation , studentParentAssociation , or staffSchoolAssociation.

## HTTP Request 1

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/parents
Authorization: Bearer fd964160527941a39875e821d2622088 
Content-Type: application/json; charset=utf-8

{
  "parentUniqueId": "123456789",
  "firstName": "Amelia",
  "lastSurname": "Earhart"
}

## HTTP Response 1

HTTP 1.1 201 Created
location: https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/parents/3f375bc2ac5c4a709a168616afb4772e 

## HTTP Request 2

GET https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/parents/3f375bc2ac5c4a709a168616afb4772e   
Authorization: Bearer fd964160527941a39875e821d2622088

## HTTP Response 2
{
  "message": "Authorization denied. No relationships have been established between the caller's education organization id claims (255901, 19255901) and the resource item's 'ParentUniqueId' value."
}

## In the analogous cases for Student and Staff, the second response will be:

{
  "message": "Authorization denied. No relationships have been established between the caller's education organization id claims (255901, 19255901) and the resource item's 'StudentUniqueId' value."
}

{
  "message": "Authorization denied. No relationships have been established between the caller's education organization id claims (255901, 19255901) and the resource item's 'StaffUniqueId' value."
}

How to Resolve

Problem seems likely to be in the application code → send to application development team for resolution.

  • Be sure to create an appropriate StudentSchoolAssociation , studentParentAssociation , or staffSchoolAssociation record only after creating the corresponding Student , Parent, or Staff  object. 

However, it is conceivable that there is a data problem in the source system, which caused a failure to create the correction Association. It may be necessary to look at earlier error logs to look for a different problem that needs to be resolved in the source system.

Not Authorized for a School or Education Organization 

This is similar to the student / parent / staff problem above. In this case, the client credentials are not configured for access to a given School Id. This is a security measure so that, for example, a source system that is only supposed to access certain schools in a local education agency (say, all middle schools), cannot gain access to other schools.

Example: cannot create a Class Period for a different school

## HTTP Request 1

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/classPeriods
Authorization: Bearer fd964160527941a39875e821d2622088 
Content-Type: application/json; charset=utf-8

{
  "schoolReference": {
    "schoolId": 55901001
  },
  "classPeriodName": "01 - Traditional",
  "meetingTimes": [
    {
      "endTime": "09:25:00",
      "startTime": "08:35:00"
    }
  ]
}

## HTTP Response 1

HTTP 1.1 403 Forbidden

{
  "message": "Authorization denied. No relationships have been established between the caller's education organization id claims (255901, 19255901) and the resource item's 'SchoolId' value."
}

Example: cannot create an Education Organization Association when the credentials are scoped to a particular school.

## HTTP Request 1

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/studentEducationOrganizationAssociations
Authorization: Bearer fd964160527941a39875e821d2622088 
Content-Type: application/json; charset=utf-8

{
  "studentReference": {
    "studentUniqueId": "604822",
  },
  "educationOrganizationReference": {
    "educationOrganizationId": 1
  }
}

## HTTP Response 1

HTTP 1.1 403 Forbidden

{
  "message": "Authorization denied. No relationships have been established between the caller's education organization id claim (2) and one or more of the following properties of the resource item: 'EducationOrganizationId', 'StudentUniqueId'."
}

How to Resolve

The problem could be in application → have the application development team check first:

  • Is the correct schoolId  being transmitted?
  • Interestingly, this also occurs if the school does not exist. This is a precaution so that a malicious system cannot "fish" for the existence of otherwise legitimate schoolId 's that they should not be able to access.

If that is correct, then it could be a credential access problem → send the client key to the hosting provider / IT operations:

  • Using a tool like Admin API or Admin App, confirm that the key is configured for access to the given school or education organization.

Not Authorized for Access to the School

The example above was for managing relationships. This is about managing resources that are attached to schools. In this example, the client ID was given explicit access to a specific school, other than the one used in the payload.

## HTTP Request 1

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/classPeriods
Authorization: Bearer fd964160527941a39875e821d2622088 
Content-Type: application/json; charset=utf-8

{
  "bellScheduleName": "one",
  "classPeriods": [],
  "schoolReference": {
    "schoolId": 255901
  }
}

## HTTP Response 1

HTTP 1.1 403 Forbidden

{
  "message": "Authorization denied.  Access to the requested 'SchoolId' was denied."
}

How to Resolve

The problem could be in application → have the application development team check first:

  • Is the correct schoolId  being transmitted?
  • Interestingly, this also occurs if the school does not exist, or if the ID belongs to a non-school type of Education Organization. This is a precaution so that a malicious system cannot "fish" for the existence of otherwise legitimate schoolId 's that they should not be able to access.

If that is correct, then it could be a credential access problem → send the client key to the hosting provider / IT operations:

  • Using a tool like Admin API or Admin App, confirm that the key is configured for access to this school.

Invalid Namespace Prefix

Most of these 403 message refer to the portion of the Ed-Fi ODS/API that uses the client's relationship to an education organization as the basis for resource authorization. There is another approach to securing access to resources, which is particularly used with Assessments: namespace prefix. When an API client is created, it is given access to one or more namespace prefixes. For resources secured by namespace, the client credentials can only perform actions on objects that match the assigned namespace prefix. In the following example, the namespace prefix is "uri://ed-fi.org", but the client credentials were configured for "uri://example.com" instead.

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/assessments
Authorization: Bearer 6f5bb488a65948b5b847b561b23e 
Content-Type: application/json; charset=utf-16

{
  "assessmentIdentifier": "_01774fa3-06f1-47fe-8801-c8b1e65057f3_",
  "namespace": "uri://ed-fi.org/Assessment/Assessment.xml",
  "assessmentCategoryDescriptor": "uri://ed-fi.org/AssessmentCategoryDescriptor#Benchmark test",
  "assessmentTitle": "3rd Grade Reading 1st Six Weeks 2021-2022",
  "academicSubjects": [
    {
      "academicSubjectDescriptor": "uri://ed-fi.org/AcademicSubjectDescriptor#English Language Arts"
    }
  ],
  "identificationCodes": [
    {
      "assessmentIdentificationSystemDescriptor": "uri://ed-fi.org/AssessmentIdentificationSystemDescriptor#Test Contractor",
      "identificationCode":  "01774fa3-06f1-47fe-8801-c8b1e65057f3"
    }
  ],
  "scores": [
    {
      "assessmentReportingMethodDescriptor": "uri://ed-fi.org/AssessmentReportingMethodDescriptor#Percentile",
      "maximumScore": "99",
      "minimumScore": "1",
      "resultDatatypeTypeDescriptor": "uri://ed-fi.org/ResultDatatypeTypeDescriptor#Integer"
    }
  ],
}

## HTTP Response

HTTP/1.1 403 Forbidden 
Content-Type: application/json; charset=utf-8

{
  "message": "Access to the resource item could not be authorized based on the caller's NamespacePrefix claims: 'uri://example.com'."
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Ensure that the correct namespace is used in the payload. The error message itself indicates what the correct namespace should be.

The Requested Action Is Not Permitted

Credentials to the Ed-Fi ODS/API are configured with a claim set that defines what the credentials are allowed to do. The following error message indicates that the API client has tried to take an action - in this case, updating a Descriptor - that is not allowed under this claim set.

## HTTP Request

PUT https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/absenceEventCategoryDescriptors/3a62029e71374c7095d288a6cabae206
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-16

{
  "id": "3a62029e71374c7095d288a6cabae206",
  "codeValue": "Compensatory leave time",
  "description": "Compensatory leave time",
  "namespace": "uri://ed-fi.org/AbsenceEventCategoryDescriptor",
  "shortDescription": "Compensatory leave time"
}

## HTTP Response

HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8

{
  "message": "Access to the resource could not be authorized for the requested action 'http://ed-fi.org/odsapi/actions/update'."
}

How to Resolve

Problem may be in the application code → send to application development team for resolution.

  • Should not be performing this action.

On the other hand, if the application development team believes this ought to be a permitted action, then please contact the hosting provider (external) or IT operations (internal hosting) to discuss replacing the credentials with a new client id / secret pair that has greater latitude for action.

Missing Claim

## HTTP Request

PUT https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/chartOfAccounts
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-8
 
{
  "educationOrganizationReference": {
    "educationOrganizationId": 255901
  },
  "fundDimensionReference": {
    "code": "1",
    "fiscalYear": 4022
  },
  "accountIdentifier": "1-1-1000-000",
  "fiscalYear": 2022,
  "accountName": "TOTAL REVENUE FROM LOCAL SOURCES",
  "accountTypeDescriptor": "uri://ed-fi.org/AccountTypeDescriptor#Revenue"
}


## HTTP Response

HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8  

{
  "message": "Access to the resource could not be authorized. Are you missing a claim? This resource can be authorized by the following claims:\r\n    http://ed-fi.org/ods/identity/claims/ed-fi/chartOfAccount\n    http://ed-fi.org/ods/identity/claims/domains/finance/locals\n    http://ed-fi.org/ods/identity/claims/domains/finance\r\nThe API client has been assigned the 'SIS Vendor' claim set with the following resource claims:\r\n    http://ed-fi.org/ods/identity/claims/domains/edFiTypes\n    http://ed-fi.org/ods/identity/claims/domains/systemDescriptors\n    http://ed-fi.org/ods/identity/claims/domains/managedDescriptors\n    http://ed-fi.org/ods/identity/claims/domains/educationOrganizations\n    http://ed-fi.org/ods/identity/claims/domains/people\n    http://ed-fi.org/ods/identity/claims/domains/relationshipBasedData\n    http://ed-fi.org/ods/identity/claims/domains/assessmentMetadata\n    http://ed-fi.org/ods/identity/claims/domains/educationStandards\n    http://ed-fi.org/ods/identity/claims/domains/primaryRelationships\n    http://ed-fi.org/ods/identity/claims/educationContent"
}

How to Resolve

Problem may be in the application code → send to application development team for resolution.

  • Should not be performing this action with this key/secret.

On the other hand, if the application development team believes this ought to be a permitted action, then please contact the hosting provider (external) or IT operations (internal hosting) to discuss replacing the credentials with a new client id / secret pair that uses a different claimset.

Status 404 Not Found

Resource Name Typo

## HTTP Request 1

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/academicWeek
Authorization: Bearer fd964160527941a39875e821d2622088 
Content-Type: application/json; charset=utf-8

{
  "weekIdentifier": "one",
  "beginDate": "2023-09-11",
  "endDate": "2023-09-11",
}

## HTTP Response 1

HTTP/1.1 404 Not Found

How to Resolve

The problem is in the application → send to the application development team:

  • Review the exact URL / route for accuracy.
    • In this case, "academicWeek" should be pluralized to "academicWeeks"
  • If the host provides Swagger UI, use it to confirm the exact path on the URL.
  • If everything looks correct, ask the hosting provider if they are running in an instance mode that introduces an additional segment into the URL, for example the school year or a district name.

ID Does Not Exist

Also applies to DELETE requests.

## HTTP Request 1

PUT https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/academicWeek/not-valid-id
Authorization: Bearer fd964160527941a39875e821d2622088 
Content-Type: application/json; charset=utf-8

{
  "weekIdentifier": "one",
  "beginDate": "2023-09-11",
  "endDate": "2023-09-11",
}

## HTTP Response 1

HTTP/1.1 404 Not Found

How to Resolve

The problem is in the application → send to the application development team:

  • If the route is fully correct, and the ID is wrong, then may need to perform a GET request by natural key to lookup the correct ID before issuing a PUT or DELETE request.

Accidental Space at End of the URL

If a space gets encoded onto an otherwise valid URL with %20  then you may get an interesting 404 with an extensive response body coming from the webserver (e.g. IIS in Windows) instead of coming from the API application itself.

For example, the following is a valid URL: 

https://api.ed-fi.org:443/v6.1/api/data/v3/ed-fi/academicWeeks/5a70e28f3ac242a2ac26e8caea141d9f

But this one is not because of %20 at the end - the URL encoding for a space.

https://api.ed-fi.org:443/v6.1/api/data/v3/ed-fi/academicWeeks/5a70e28f3ac242a2ac26e8caea141d9f%20

On IIS, this generates a 404 with the following text response:

<!DOCTYPE html>
<html>
    <head>
        <title>The resource cannot be found.</title>
        <meta name="viewport" content="width=device-width" />
        <style>
         body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} 
         p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
         b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
         H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
         H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
         pre {font-family:"Consolas","Lucida Console",Monospace;font-size:11pt;margin:0;padding:0.5em;line-height:14pt}
         .marker {font-weight: bold; color: black;text-decoration: none;}
         .version {color: gray;}
         .error {margin-bottom: 10px;}
         .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:pointer; }
         @media screen and (max-width: 639px) {
          pre { width: 440px; overflow: auto; white-space: pre-wrap; word-wrap: break-word; }
         }
         @media screen and (max-width: 479px) {
          pre { width: 280px; }
         }
        </style>
    </head>

    <body bgcolor="white">

            <span><H1>Server Error in '/v6.1/api' Application.<hr width=100% size=1 color=silver></H1>

            <h2> <i>The resource cannot be found.</i> </h2></span>

            <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">

            <b> Description: </b>HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly.
            <br><br>

            <b> Requested URL: </b>/v6.1/api/data/v3/ed-fi/academicWeeks/5a70e28f3ac242a2ac26e8caea141d9f<br><br>

            </font>

    </body>
</html>

Status Code 405 Method Not Allowed

Submitting PUT Request with ID

The ODS/API blocks PUT requests that have an id  value. This was a mistake in the past, based on POST requests blocking the id. However, a PUT request should contain the entire body of the object that is being saved, therefore it should contain the id. This affects ODS/API versions prior to 7.0; that is, the problem has been resolved in 7.0. At least for 7.x, the application is lenient enough that it continues to allow PUT requests without the id, in order to avoid causing too much trouble for existing application integrations. That leniency isn't required in all API implementations and this my become strict in a future release.

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • The Ed-Fi id  value can be found either:
    • In the location header returned from a POST request, or
    • By doing a GET request and pulling the id  from the response
  • Append the id  value, 
  • Remove the id value from the payload in PUT requests targeting ODS/API < 7.0.

DELETE or PUT Request without an ID in the URL

DELETE and PUT requests must have an Ed-Fi ID value in the URL to point to the exact record to remove or modify.

## HTTP Request

PUT https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/studentAcademicRecords
Authorization: Bearer fd964160527941a39875e821d2622088 
Content-Type: application/json; charset=utf-8

{
  "id": "d074a26cec7449299f701ba54e0f0257",
  "educationOrganizationReference": {
    "educationOrganizationId": 255901001
  },
  "schoolYearTypeReference": {
    "schoolYear": 2022
  },
  "studentReference": {
    "studentUniqueId": "604874"
  },
  "termDescriptor": "uri://ed-fi.org/TermDescriptor#Fall Semester",
  "gradePointAverages": [
    {
      "gradePointAverageTypeDescriptor": "uri://ed-fi.org/GradePointAverageTypeDescriptor#Unweighted",
      "gradePointAverageValue": 4,
      "isCumulative": true
    }
  ]
}

## HTTP Response

HTTP/1.1 405 Method Not Allowed

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • The Ed-Fi id  value can be found either:
    • In the location header returned from a POST request, or
    • By doing a GET request and pulling the id  from the response
  • Append the id  value at the end of the URL. In this case, the URL should be https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/studentAcademicRecords/d074a26cec7449299f701ba54e0f0257

Status Code 409 Conflict

Duplicate Values for Descriptor codeValue and namespace

This is an interesting edge case. Normally, the ODS/API performs an "upsert" when it receives a POST request: if the natural key already exists on a record, then it updates that record to match the new request body. However, in the case of descriptors there are two ways to generate a 409 conflict instead.

Example: this occurs if the xyzDescriptorId  value is present in the payload, as shown below.

## HTTP Request

POST https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors
Authorization: bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-8

{
  "absenceEventCategoryDescriptorId": 1,
  "codeValue": "Bereavement",
  "shortDescription": "Bereavement",
  "namespace": "uri://ed-fi.org/AbsenceEventCategoryDescriptor"
}

##  HTTP Response when the ODS/API is using SQL Server

HTTP/1.1 409 Conflict
Content-Type: application/json; charset=utf-8

{
  "message": "The values unknown supplied for properties 'codeValue', 'namespace' of entity 'descriptor' are not unique."
}

## HTTP Response when the ODS/API is using PostgreSQL
 
HTTP/1.1 409 Conflict
Content-Type: application/json; charset=utf-8 

{
  "message": "The value unknown supplied for property 'unknown' of entity 'descriptor' is not unique."
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Although it is normally harmless, do not transmit a xyzDescriptorId  value in the payload.

Example: ID mismatch causing accidental attempt to change natural key of an object to values that already exist on another object

## HTTP Request 1 - Create a descriptor

POST https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors
Authorization: bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-8

{
  "codeValue": "Compensatory leave time",
  "description": "Compensatory leave time",
  "namespace": "uri://ed-fi.org/AbsenceEventCategoryDescriptor",
  "shortDescription": "Compensatory leave time"
}

## HTTP Response 1

HTTP 201 Created
Location: https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors/33f6cc63fd4c4b7380eb5bd7333ad8df

## HTTP Request 2 - ⚠ oops, re-using the LOCATION above for a completely different Absence Event Category Descriptor!

PUT https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors/33f6cc63fd4c4b7380eb5bd7333ad8df
Authorization: bearer 6f5bb488a65948b5b847b561b23e
Content-Type: application/json; charset=utf-8

{
  "id": "33f6cc63fd4c4b7380eb5bd7333ad8df"
  "codeValue": "Bereavement",
  "shortDescription": "Bereavement",
  "namespace": "uri://ed-fi.org/AbsenceEventCategoryDescriptor"
}

##  HTTP Response

HTTP/1.1 409 Conflict
Content-Type: application/json; charset=utf-8

{
  "message": "The values unknown supplied for properties 'codeValue', 'namespace' of entity 'descriptor' are not unique."
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • When issuing a PUT request for a Descriptor, it is best to avoid updating the natural key values for codeValue  and namespace .
  • Additionally, review the call and make sure that ID value in the URL and payload are the correct ones for the Descriptor that you wish to update.

Missing Student or Staff

Naturally, the person (student, staff) must exist for creation of another object that relates to that person to succeed. Interestingly, this case runs into an authorization problem in the Ed-Fi ODS/API before it can fail due to the referential integrity constraint.

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/staffSectionAssociations
Authorization: Bearer 6f5bb488a65948b5b847b561b23e 
Content-Type: application/json; charset=utf-8

{
  "sectionReference": {
    "localCourseCode": "ALG-1",
    "schoolId": 255901001,
    "schoolYear": 2022,
    "sectionIdentifier": "25590100102Trad220ALG112011",
    "sessionName": "2021-2022 Fall Semester"
  },
  "staffReference": {
    "staffUniqueId": "207270__"
  },
  "beginDate": "2021-08-23",
  "classroomPositionDescriptor": "uri://ed-fi.org/ClassroomPositionDescriptor#Teacher of Record",
  "endDate": "2021-12-17"
}

##  HTTP Response

HTTP/1.1 409 Conflict 
Content-Type: application/json; charset=utf-8

{
  "message": "Access to the resource item could not be authorized because the 'Staff' was not found."
}

## Alternately for a missing student in studentSectionAssociations:

HTTP/1.1 409 Conflict 
Content-Type: application/json; charset=utf-8

{
  "message": "Access to the resource item could not be authorized because the 'Student' was not found."
}

How to Resolve

Problem seems likely to be in the application code → send to application development team for resolution.

  • Be sure to create an appropriate association record only after creating the corresponding Student , Parent, or Staff  object.
  • Interestingly, does not apply to studentSchoolAssociations - in that case, we simply have a normal 400 "reference could not be resolved" type of message.

However, it is conceivable that there is a data problem in the source system, which caused a failure to create the correction Association. It may be necessary to look at earlier error logs to look for a different problem that needs to be resolved in the source system.

Invalid Reference

The ODS/API application enforces referential integrity: whenever a property is named ___Reference, the key values in that reference must match the values on an existing object in the database. 

Example: In this example we have two references that could cause the POST (or a similar PUT request) to be rejected: the school, and the school year. School year is unusual in the ODS/API in that it comes preconfigured. By default, the Ed-Fi ODS/API recognizes school years 1991-2050. Each implementation can change that list through the edfi.SchoolYearType  table. There is a schoolYearTypes  resource in the API; however, not all credentials are able to access it.

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/calendars
Authorization: Bearer 6f5bb488a65948b5b847b561b23e 
Content-Type: application/json; charset=utf-8

{
  "schoolReference": {
    "schoolId": 255901107
  },
  "schoolYearTypeReference": {
    "schoolYear": 4022
  },
  "calendarCode": "2010605675",
  "calendarTypeDescriptor": "uri://ed-fi.org/CalendarTypeDescriptor#Student Specific"
}

##  HTTP Response

HTTP/1.1 409 Conflict 
Content-Type: application/json; charset=utf-8

{
  "message": "The value supplied for the related 'schoolYearType' resource does not exist."
}

Example: this chartOfAccounts is referencing a fundDimension that does not exist yet.

## HTTP Request

POST https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/chartOfAccounts
Authorization: Bearer 6f5bb488a65948b5b847b561b23e 
Content-Type: application/json; charset=utf-8

{
  "educationOrganizationReference": {
    "educationOrganizationId": 255901
  },
  "fundDimensionReference": {
    "code": "1_",
    "fiscalYear": 2022
  },
  "sourceDimensionReference": {
    "code": "1000",
    "fiscalYear": 2022
  },
  "accountIdentifier": "1-1-1000-000",
  "fiscalYear": 2022,
  "accountName": "TOTAL REVENUE FROM LOCAL SOURCES",
  "accountTypeDescriptor": "uri://ed-fi.org/AccountTypeDescriptor#Revenue",
  "reportingTags": [
    {
      "reportingTagDescriptor": "uri://ed-fi.org/ReportingTagDescriptor#LEA",
      "tagValue": "$308,136,446"
    }
  ]
}

##  HTTP Response

HTTP/1.1 409 Conflict Content-Type: application/json; charset=utf-8

{
  "message": "The value supplied for the related 'fundDimension' resource does not exist."
}

How to Resolve

Problem might be in the application code → send to application development team for resolution.

  • Be sure to submit data following the required Resource Dependency Order.
  • For school year: if the year is correct, and still getting the error, check with the API hosting provider to find out what school years are allowed.

Alternately, the code might be correct, and there could be an "upstream" problem → send for application user review.

  • Was there an error when synchronizing the upstream resource, such that it did not save correctly? In the above example, look to see if there was an error when creating the fundDimension. If so, might need to correct something on one or more Student records in order to complete the Student synchronization and then re-try the chartOfAccounts  synchronization.

Cannot Delete A Resource That Has Dependencies

This is what happens when you try to delete Resource A that has Resource B depending on it. Example: cannot delete a particular School when there are StudentSchoolAssociations tied to that School.

## HTTP Request

DELETE https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/schools/d6af41d20de34b9cb4676d5f58c4f673
Authorization: Bearer 6f5bb488a65948b5b847b561b23e

##  HTTP Response - Example 1

HTTP/1.1 409 Conflict Content-Type: application/json; charset=utf-8

{
  "message": "The resource (or a subordinate entity of the resource) cannot be deleted because it is a dependency of the 'schoolId' value of the 'studentSchoolAssociation' entity."
}

## HTTP Response - Example 2

HTTP/1.1 409 Conflict Content-Type: application/json; charset=utf-8

{
  "message": "The resource (or a subordinate entity of the resource) cannot be deleted because it is a dependency of the 'locationSchoolId' value of the 'section' entity."
}

How to Resolve

Problem might be in the application code → send to application development team for resolution.

  • Be sure to delete data in reverse Resource Dependency Order.
  • The message has useful detail about the dependency with the problem. (warning) However, it only lists the first dependency problem, and there may be more. The second example above only mentions section as a dependency. However, that API installation also has session objects that depend on the same schoolId , and that isn't mentioned by the error message. The number of possible dependencies is simply too large to report them all here.

Status Code 412 Precondition Failed

The only occurs when opting into the eTag feature. First, the API client must have retrieved a record by ID or by any query. The response body will contain an _etag  property. That _etag  value can then be used in a If-Match  header on a PUT request. If a different API client updates the resource before your client can do so, the _etag value will have changed and the If-Match  fails, resulting in Status Code 412.

## HTTP Request - GET an academicWeek by school and weekIdentifier

GET https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/academicWeeks?weekIdentifier=one&schoolId=3962030
Authorization: Bearer 6f5bb488a65948b5b847b561b23e

##  HTTP Response 1

HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8

[
  {
    "id": "5a70e28f3ac242a2ac26e8caea141d9f",
    "schoolReference": {
      "schoolId": 3962030,
      "link": {
        "rel": "School",
        "href": "/ed-fi/schools/9921bc860fcb44eeb22199a1baa90bcb"
      }
    },
    "weekIdentifier": "one",
    "beginDate": "2023-09-11",
    "endDate": "2023-09-11",
    "totalInstructionalDays": 0,
    "_etag": "5249986526304019307",
    "_lastModifiedDate": "2023-09-11T17:39:47.6631403Z"
  }
]

## HTTP Response - PUT request, assuming another client came in between and
# already updated the object, causing an _etag mismatch. Notice the extra
# If-Match header

PUT https://api.ed-fi.org/v6.1/api/data/v3/ed-fi/academicWeeks/5a70e28f3ac242a2ac26e8caea141d9f
Authorization: Bearer 6f5bb488a65948b5b847b561b23e
If-Match: 5249986526304019307

{
  "id": "5a70e28f3ac242a2ac26e8caea141d9f",
  "schoolReference": {
    "schoolId": 3962030
  },
  "weekIdentifier": "one",
  "beginDate": "2023-09-11",
  "endDate": "2023-09-11",
  "totalInstructionalDays": 0
}

## HTTP Response 2

HTTP/1.1 412 Precondition Failed Content-Type: application/json; charset=utf-8

{
  "message": "Resource was modified by another consumer."
}

How to Resolve

Problem might be in the application code → send to application development team for resolution. 

One possible workflow for correcting the issue:

  • Retrieve the object again.
  • Update only the fields that should be the "exclusive" domain of your API client.
  • Re-submit the PUT request.

Status Code 415 Unsupported Media Type

This occurs when the content-type header is missing or is not "application/json".

## HTTP Request

POST https://api.ed-fi.org:443/v5.3/api/data/v3/ed-fi/absenceEventCategoryDescriptors
Authorization: bearer 6f5bb488a65948b5b847b561b23e

{
  "description": "Bereavement",
  "namespace": "uri://ed-fi.org/AbsenceEventCategoryDescriptor"
}

##  HTTP Response

HTTP/1.1 415 Unsupported Media Type 
Content-Type: application/json; charset=utf-8

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.13",
  "title": "Unsupported Media Type",
  "status": 415,
  "traceId": "00-a439f7d968fa0896972bd8ed9e3b0b8b-4543614e103e7291-00"
}

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Be sure to provide the header Content-Type: application/json.
  • The charset  is optional and assumed to be UTF-8 when omitted.

Status Code 500 Internal Server Error

This is a catch-all for various errors that can occur on the server. Review this section for possible reasons for the error.

Missing Content-Type Header on Token Requests

When the content-type  header is missing for OAuth Token and Token Info requests, then the ODS/API generates a 500 response. Ideally, this should be 415 response. The HTTP response to the client does not have sufficient information to resolve the issue, and the API's error log entry is not intuitive. However, it is diagnostic in that this is the only cause for the error message shown below.

## HTTP Request  

POST https://api.ed-fi.org/v6.1/api/oauth/token 
Authorization: Basic UnZjS3o5ekhJNDpFMWlFRnVzYU5mODF4ekN4d0hmYmtD==

grant_type=client_credentials

## HTTP Response

HTTP/1.1 500 Internal Server Error

## Log Entry, look for:

AmbiguousMatchException: The request matched multiple endpoints

How to Resolve

Problem is in the application code → send to application development team for resolution.

  • Be sure to provide the header Content-Type: application/json.
  • The charset  is optional and assumed to be UTF-8 when omitted.