Table of Contents
- Purpose of the Document
- Authentication prerequisite
- Context
- Base URL
- TMF Filter
- General Information on the Technical Solution
- Lifecycle of Tickets
- Errors
Purpose of the Document
This document describes version 1.0 of the standardized tool defined by the Interop’fibre Group for the creation or modification of IPE addresses by the infrastructure operator following a request from the commercial operator.
Glossary Refer to the definitions provided online by ARCEP: File
Acronym or Concept :
OI - Building Operator: Any person responsible for establishing or managing one or more lines within a constructed building, notably under an agreement for installation, maintenance, replacement, or management of lines signed with the owner or the condominium association, as per Article L. 33-6 of the French Postal and Electronic Communications Code; the building operator is not necessarily an operator under Article L. 33-1 of the same code.
OC - Commercial Operator: Operator chosen by the end customer for the provision of a telecommunications service or by an access service provider for providing a telecommunications service to its own end customer.
GitHub Documentation : documentation
Authentication prerequisite
Access to this API is secured by the OAuth 2.0 framework with the Client Credentials grant type, which means that you will have to present an OAuth 2.0 access_token whenever you want to request this API.
It's easy to negotiate this access_token: just send a request to the proper token negotiation endpoint, with a Basic Authentication header valued with your own client_id and client_secret.
For this API, the token negotiation endpoint is:
TOKEN SECTION
https://api.orange.com/oauth/v2/token
A technical guide is available to learn how to negotiate and manage these access_token.
SDK to manage token lifecycle could help you to implement cache token.
Context
This tool was created to comply with the regulatory obligation outlined in ARCEP Decision No. 2020-1432. It facilitates the processing of requests to create or modify building addresses in the IPE using standardized workflows.
Excerpt from ARCEP Decision No. 2020-1432 : “Given the importance of IPE files in determining eligibility on FttH networks, it seems reasonable to require infrastructure operators to establish an inter-operator process enabling commercial operators to report missing or incorrect buildings. As with other inter-operator processes, such a reporting process should ideally be identical across all infrastructure operators to allow commercial operators to streamline the necessary developments.”
Process Processing times are defined by type, as stated in ARCEP Decision No. 2020-1432 (Section 2.3.1): Excerpt from ARCEP Decision No. 2020-1432: “For individual reports, whether grouped or not, it seems reasonable for the infrastructure operator to correct the error or add the building within one week of the report if it’s a simple case, or, in the case of a complex situation, to inform the commercial operator of the additional time required. This one-week timeframe appears reasonable considering operational processes already used by infrastructure operators to implement the one-calendar-day update requirement as per ARCEP Decision No. 2015-0776. Moreover, it is particularly important for the commercial operator to provide the end customer with reasonable visibility within this timeframe. In any case, the aforementioned additional time should not exceed three weeks, even for the most complex cases.
For bulk reports, it seems reasonable for the timeframe to be longer, considering the need for potentially heavier processing to systematically correct a large amount of data, without exceeding two months.”
Validated definitions by the Interop Working Group:
- Simple Case: Does not require on-site intervention, network intervention, or alignment of reference systems.
- Complex Case: Any case that is not simple.
The process must address two categories of address referencing anomalies :
- Individual Reports: For example, an anomaly detected based on a customer complaint. This involves a report affecting a single IPE line.
- Bulk Reports: For example, a list of anomalies detected through automated checks with a common criterion (e.g., anomalies in the same field). These involve reports affecting two or more IPE lines. Certain criteria must relate to the same geographical area.
The list of common criteria is not exhaustive and may be expanded at the request of an operator upon consensus validation by the Infrastructure Working Group. List-criteria-bulk-report
The number of lines allowed for bulk reporting will be defined bilaterally between the OI and the OC concerned.
Address anomaly tickets are processed up to the point of registering the address in the IPE, regardless of the deployment status.
Base URL
The Base URL is the first part of the full invocation URL, just before the resource paths. Whenever you make requests on this API, you will need to prepend the following Base URL to the resource paths defined for this API.
If you request this API and encounter a 404 NOT FOUND HTTP error response, please check first that the Base URL is correct.
The Base URL for this API is:
https://api.orange.com/anomalie-adresse
Resources
Get an AnomalieAdresse by id
Request
curl -X GET -H "Authorization: Bearer {access_token}" \
https://api.orange.com/anomalie-adresse/:id
Response
Headers
HTTP/1.1 200 OK
X-Result-Count: 1
X-Total-Count: 1
Body
[
{
"@type": "AnomalieAdresse.modification",
"id": "22e61758-924d-4ad7-b259-e4fcb1ea8808",
"status": "ACKNOWLEDGED",
"statusAuthor": null,
"statusChangeReason": null,
"statusChangeDetails": null,
"statusChangeDate": null,
"name": "MLE",
"description": "test MLE",
"severity": null,
"priority": null,
"complexity": null,
"externalId": null,
"resolutionDate": null,
"expectedResolutionDate": null,
"requestedResolutionDate": null,
"acknowledgedDuration": 0,
"totalInProgressDuration": 0,
"totalPendingDuration": 0,
"resolvedToInProgressDuration": 0,
"resolvedToClosedDuration": 0,
"resolvedToAcknowledgedDuration": 0,
"code_oi": "ARTD",
"code_oc": "ARTD",
"siret": null,
"siren": null,
"ticketType": "OC_REQUEST",
"statusChanges": [
{
"status": "ACKNOWLEDGED",
"changeDate": "2025-01-14T13:17:58.078+00:00",
"@type": "StatusChange",
"@baseType": "StatusChange",
"@schemaLocation": "https://raw.githubusercontent.com/tmforum-rand/schemas/candidates/Common/StatusChange.schema.json"
}
],
"relatedEntity": [
{
"id": "IMB/09001/X/000E",
"@type": "RelatedEntity",
"@baseType": "RelatedEntity",
"@referredType": "Building"
},
{
"id": "IMB/09001/X/000Q",
"@type": "RelatedEntity",
"@baseType": "RelatedEntity",
"@referredType": "Building"
}
],
"relatedParty": [],
"@version": "a6b22c4a-8e16-41d0-beac-c5a4e1f0fdc9",
"zone": null,
"@baseType": "TroubleTicket",
"@schemaLocation": "https://raw.githubusercontent.com/tmforum-apis/Open_Api_And_Data_Model/master/schemas/Common/TroubleTicket.schema.json",
"issues": {
"building.geographicLocations": null,
"building.name": null,
"building.address.city": null,
"building.address.postcode": null,
"building.address.streetName": null,
"building.address.streetNr": null,
"building.address.streetNrSuffix": null,
"building.address.streetType": null,
"building.address.code_insee": null,
"building.address.code_hexacle": null,
"building.address.code_hexacle_voie": null,
"building.address.code_rivoli": null,
"building.address.code_ban": null,
"building.pm.id": {
"description": "toto",
"value": "test"
}
}
}
]
Detailed information about all the resources of this API: check the API reference
TMF Filter
With the TFM Filter you can adapt your request to the API :
Paging
You can paginate the results of a query by using the offset and limit query parameters. Offset defines the number of elements to skip before returning the results, default is 0. Limit defines the maximum number of elements to return, default is 10.
Examples
```bash
# Get the first 10 elements (default comportment without query parameters)
curl -X GET "https:<endpointUrl>"
# Get the 100 elements after the 100th element
curl -X GET "https:<endpointUrl>?offset=100&limit=100"
```
Sorting
You can sort the results of a query by one or more fields in ascending or descending order by using the sort query parameter.
To sort in ascending order, set the value of the query parameter to the name of the field, optionally you can prefix it by +. To sort in descending order, set the value of the query parameter to the name of the field prefixed by -.
Examples
```bash
# Sort by name in ascending order and then by id in descending order
curl -X GET "https:<endpointUrl>?sort=+name,-id"
# Same request but without optional ascending order prefix
curl -X GET "https:<endpointUrl>?sort=name,-id"
```
Selecting fields
You can choose the fields returned by a query by using the fields query parameter. This parameter is a comma separated list of fields to return. Values are limited to the first level fields of the queried entity.
Examples
```bash
# Return only the name and id fields
curl -X GET "https:<endpointUrl>?fields=name,id"
```
###Filtering
You can filter the results of a query by using query parameters. Put in query parameters the name of the field you want to filter optionally prefixed by an operator alias between [] and the value you want to filter on.
```bash
curl -X GET "https:<endpointUrl>?<fieldName>[<operatorAlias>]=<value>"
```
Operators
Available operators are:
- Equal
- Not Equal
- Greater Than
- Greater Than Or Equal
- Less Than
- Less Than Or Equal
- Match
- Not Match
- Is
- Is Not
- In
- Not In
- Element Match Json
- Not Element Match Json
Equal
Selected field equals the specified value. Operator by default if no operator alias is specified.
Aliases
eq==
Supported Typed Searches
Examples
```bash
curl -X GET "https:<endpointUrl>?name=doudou"
curl -X GET "https:<endpointUrl>?name[eq]=doudou"
curl -X GET "https:<endpointUrl>?name[==]=doudou"
curl -X GET "https:<endpointUrl>?adress.city.zipcode=31000"
curl -X GET "https:<endpointUrl>?adress.streetnumber[eq,num]=10"
```
Not Equal
Selected field does not equal the specified value.
Aliases
ne!=<>neq!eq
Supported Typed Searches
Examples
```bash
curl -X GET "https:<endpointUrl>?name[ne]=doudou"
curl -X GET "https:<endpointUrl>?name[!=]=doudou"
curl -X GET "https:<endpointUrl>?name[<>]=doudou"
curl -X GET "https:<endpointUrl>?name[neq]=doudou"
curl -X GET "https:<endpointUrl>?name[!eq]=doudou"
curl -X GET "https:<endpointUrl>?adress.streetnumber[!eq,num]=10"
```
Greater Than
Selected field is greater than the specified value.
Aliases
gt>
Supported Typed Searches
Examples
```bash
curl -X GET "https:<endpointUrl>?age[gt,num]=18"
curl -X GET "https:<endpointUrl>?birthdate[>]=2020-01-10"
curl -X GET "https:<endpointUrl>?word[>]=b"
```
Greater Than Or Equal
Selected field is greater than or equal to the specified value.
Aliases
gte>=
Supported Typed Searches
Examples
```bash
curl -X GET "https:<endpointUrl>?age[gte,num]=18"
curl -X GET "https:<endpointUrl>?birthdate[>=]=2020-01-10"
curl -X GET "https:<endpointUrl>?word[>=]=b"
```
Less Than
Selected field is less than the specified value.
Aliases
lt<
Supported Typed Searches
Examples
```bash
curl -X GET "https:<endpointUrl>?age[lt,num]=18"
curl -X GET "https:<endpointUrl>?birthdate[<]=2020-01-10"
curl -X GET "https:<endpointUrl>?word[<]=b"
```
Less Than Or Equal
Selected field is less than or equal to the specified value.
Aliases
lte<=
Supported Typed Searches
Examples
```bash
curl -X GET "https:<endpointUrl>?age[lte,num]=18"
curl -X GET "https:<endpointUrl>?birthdate[<=]=2020-01-10"
curl -X GET "https:<endpointUrl>?word[<=]=b"
```
Match
Selected field matches the specified regular expression.
Aliases
matchregex=~re
Supported Typed Searches
- None (only regular expression expected)
Examples
```bash
curl -X GET "https:<endpointUrl>?name[match]=dou.*"
curl -X GET "https:<endpointUrl>?name[regex]=dou.*"
curl -X GET "https:<endpointUrl>?name[=~]=dou.*"
curl -X GET "https:<endpointUrl>?name[re]=dou.*"
```
Not Match
Selected field does not match the specified regular expression.
Aliases
notmatchnotregex!~nrenregexnmatch
Supported Typed Searches
- None (only regular expression expected)
Examples
```bash
curl -X GET "https:<endpointUrl>?name[notmatch]=dou.*"
curl -X GET "https:<endpointUrl>?name[notregex]=dou.*"
curl -X GET "https:<endpointUrl>?name[!~]=dou.*"
curl -X GET "https:<endpointUrl>?name[nre]=dou.*"
curl -X GET "https:<endpointUrl>?name[nregex]=dou.*"
curl -X GET "https:<endpointUrl>?name[nmatch]=dou.*"
```
Is
Selected field is of the specified type or has the specified property.
Aliases
is=
Is Possible Values
null: field value is nullnotnullornnull: field value is not nullexists: field exists in the entity including entity with the field value is nullnotexistsornexists: field does not exist in the entityempty: field value size is zeronotemptyornempty: field value size is superior to zerointorinteger: field value is an integerarray: field value is an arrayobject: field value is an objectstring: field value is a stringboolorboolean: field value is a booleandate: field value is a date
Supported Typed Searches
- None (only allowed values)
Examples
```bash
curl -X GET "https:<endpointUrl>?child[is]=null"
curl -X GET "https:<endpointUrl>?child[is]=notnull"
curl -X GET "https:<endpointUrl>?child[is]=exists"
curl -X GET "https:<endpointUrl>?child[is]=notexists"
curl -X GET "https:<endpointUrl>?changes[is]=empty"
curl -X GET "https:<endpointUrl>?changes[is]=notempty"
curl -X GET "https:<endpointUrl>?age[is]=int"
curl -X GET "https:<endpointUrl>?changes[is]=array"
curl -X GET "https:<endpointUrl>?child[is]=object"
curl -X GET "https:<endpointUrl>?name[is]=string"
curl -X GET "https:<endpointUrl>?valid[is]=bool"
curl -X GET "https:<endpointUrl>?birthday[is]=date"
```
Is Not
Selected field is not of the specified type or does not have the specified property.
Aliases
isnotisntnotnis!!is
Is Not Possible Values
Same as Is possible values
Supported Typed Searches
- None (only allowed values)
Examples
```bash
curl -X GET "https:<endpointUrl>?child[isnot]=null"
curl -X GET "https:<endpointUrl>?child[isnt]=notnull"
curl -X GET "https:<endpointUrl>?child[not]=exists"
curl -X GET "https:<endpointUrl>?child[nis]=notexists"
curl -X GET "https:<endpointUrl>?changes[!]=empty"
curl -X GET "https:<endpointUrl>?changes[isnt]=notempty"
curl -X GET "https:<endpointUrl>?age[isnot]=int"
curl -X GET "https:<endpointUrl>?changes[isnt]=array"
curl -X GET "https:<endpointUrl>?child[!is]=object"
curl -X GET "https:<endpointUrl>?name[isnt]=string"
curl -X GET "https:<endpointUrl>?valid[not]=bool"
curl -X GET "https:<endpointUrl>?birthday[isnt]=date"
```
In
Selected field is in the specified list of values.
Aliases
in
Supported Typed Searches
Examples
```bash
curl -X GET "https:<endpointUrl>?name[in]=doudou,jean,marc"
curl -X GET "https:<endpointUrl>?age[in,num]=20,30,40"
```
Not In
Selected field is not in the specified list of values.
Aliases
ninnotin!in
Supported Typed Searches
Examples
```bash
curl -X GET "https:<endpointUrl>?name[nin]=doudou,jean,marc"
curl -X GET "https:<endpointUrl>?name[notin]=doudou,jean,marc"
curl -X GET "https:<endpointUrl>?name[!in]=doudou,jean,marc"
curl -X GET "https:<endpointUrl>?age[!in,num]=20,30,40"
```
Element Match Json
This operator matches documents that contain an array field with at least one element that matches all the specified query criteria.
Aliases
emjsonelemmatchjsonemj
Supported Typed Searches
- None (Only valid json expected)
Examples
```bash
curl -X GET 'https:<endpointUrl>?childs[json]={"baseType":"myBaseType", "name":"myName", "adress":{"city":"myCity"}}'
curl -X GET 'https:<endpointUrl>?childs[eqjson]={"baseType":"myBaseType", "name":"myName", "adress":{"zipcode":"31000"}}'
curl -X GET 'https:<endpointUrl>?childs[j]={"baseType":"myBaseType", "name":"myName", "adress":{"city":"Toulouse", "zipcode":"31000", "streetNumber":10}}'
```
Not Element Match Json
This operator matches documents that does not contain an array field with at least one element that matches all the specified query criteria.
Aliases
notmjson!emjsonnemj!emj!elemmatchjson
Supported Typed Searches
- None (Only valid json expected)
Examples
```bash
curl -X GET 'https:<endpointUrl>?childs[njson]={"baseType":"myBaseType", "name":"myName"}'
curl -X GET 'https:<endpointUrl>?childs[nejson]={"baseType":"myBaseType", "name":"myName"}'
curl -X GET 'https:<endpointUrl>?childs[!json]={"baseType":"myBaseType", "name":"myName"}'
curl -X GET 'https:<endpointUrl>?childs[!j]={"baseType":"myBaseType", "name":"myName"}'
curl -X GET 'https:<endpointUrl>?childs[nj]={"baseType":"myBaseType", "name":"myName", "age":20}'
```
Typed Search
You can add the type of the field you want to filter on by adding the type in complement of the operator alias.
```bash
curl -X GET "https:<endpointUrl>?<fieldName>[<operatorAlias>,<typedSearchAlias>]=<value>"
```
Available typed search aliases are:
Numeric
This typed search alias is used to specify that the field is a numeric field. It is useful to avoid confusion between numeric and string values.
Aliases
numnumericnumber
Examples
```bash
curl -X GET "https:<endpointUrl>?age[gt,num]=30"
curl -X GET "https:<endpointUrl>?age[eq,numeric]=30"
curl -X GET "https:<endpointUrl>?age[in,number]=30,31,32"
```
General Information on the Technical Solution
Global Proposal
The proposal relies on the AnomalieAdresse API, which enables the categorization of objects for creation or modification (see details in Section 3.1).
Architecture
The following table outlines the technical layers involved in the FTTH service interface: Layer-technical
The API’s Swagger is compliant with the Interop standards and can be downloaded from GitHub (before-interop repository).
Protocols and Security
The various APIs are web services utilizing the "REST" architecture and HTTPS (HTTP and SSL) as application protocols.
The security measures for exchanges are defined through bilateral agreements between the OC (Commercial Operator) and the OI (Infrastructure Operator).
Management Rules
Authorized Use Cases
The commercial operator can submit the following types of requests in version 1.0: Use-case
Address fields include:
- CodeVoieRivoliImmeuble
- CodeInseeImmeuble
- CodePostalImmeuble
- CommuneImmeuble
- CodeAdresseImmeuble
- TypeVoieImmeuble
- NomVoieImmeuble
- NumeroVoieImmeuble
- ComplementNumeroVoieImmeuble
- BatimentImmeuble
Business Rules
The infrastructure operator categorizes the request as either a simple or complex case. The commercial operator must specify in the request if the report originates from a final customer requesting an order.
Best Practices: The Interop GT Infra document “Invariants and Best Practices” specifies for SNA updates: _"Inconsistent or missing Hexaclé code: the OI is responsible for requesting the SNA/Mediapost to update the Hexaclé." _ For business addresses, SIRET and/or SIREN numbers should be provided as needed, or the commercial operator may attach a plan as an appendix.
Bulk Requests
The commercial operator must populate a correction table in the API:
- Key (mandatory): Name of the initial field to modify
- Value (optional): Suggested new value
- Description (optional): Modification rules
Best Practices:
- For the trouble ticket (address anomalies), the OC is responsible for the relatedEntity.
- For ancillary APIs (note/attachment/event), the OI is responsible for the relatedEntity (refTroubleTicket).
- Generally, the child entity references the parent entity. Parent-child relationships will be listed in a relatedEntity table.
- The OC opens only one ticket for a bulk anomaly, including a list of buildings to correct.
- The OI processes all possible cases in the bulk request and marks the ticket as resolved. If unresolved cases remain, the OC can open individual tickets as needed.
Lifecycle of Tickets
After the creation or modification of an address, the ticket will be closed by the OI. Consequently, the daily IPE and the deltas/historical data will be updated the following day (D+1).
- A unitary ticket corresponds to a single address anomaly.
- The transition from acknowledged to rejected is only allowed before the ticket is qualified (i.e., before transitioning to InProgress).
- The protocol does not impose a limit on the number of iterations for reverting to the acknowledged state.
Types of Tickets
Address anomaly tickets must include the following information:
Creation Requests for a new address must include:
Whenever possible, at least one of the following address identification methods must be present in the creation request:
- Rivoli Quadruplet (CodeVoieRivoliImmeuble, CodeInseeImmeuble, NumeroVoieImmeuble, and, where applicable, ComplementNumeroVoieImmeuble)
- CodeAdresseImmeuble
- Code BAN
- Textual Address Fields: (CodePostalImmeuble, CommuneImmeuble, TypeVoieImmeuble, NomVoieImmeuble, NumeroVoieImmeuble, and optionally ComplementNumeroVoieImmeuble)
Modification Requests for an existing address must specify the target value of the field(s) to be updated.
The Building Identifier is mandatory for modification requests submitted by the OC for existing addresses. The OC may provide a ticket priority using the Priority attribute. The statusChangeReason attribute explains a status change, while statusChangeDetails gives additional context.
The OC may prompt the OI via notes if necessary.
Ticket States
acknowledged: The ticket is created by the OC. rejected: The ticket is rejected by the OI due to validation errors. Allowed only before transitioning to InProgress. Possible rejection reasons include:
- INVALID: Ticket is invalid (missing fields, incorrect values, etc.)
- UNKNOWN_RESOURCE: Resource not found at the OI
- UNKNOWN_ZONE: Zone is not managed by the OI
- ALREADY_RESOLVED: Resource already exists at the OI
- DUPLICATE: Duplicate requests for the same reference
- OTHER: Other reasons not covered by the protocol
inProgress: The ticket has been qualified and deemed admissible.
- Qualification: The OI categorizes the ticket as either a simple or complex case and reviews any attached documents. The OI indicates the expected processing time.
- From this state, the ticket can no longer be rejected. The regulatory time period begins from this state.
Additional Notes:
- The OC may provide updates or escalate the ticket’s priority by adding notes.
- If necessary, the OI may request additional information to process the ticket.
- A reclassification of complexity (from simple to complex) is allowed only once at the inProgress state. If this happens, the OI must update the projected resolution date, StatusChangeReason, and StatusChangeDetails.
pending (On Hold): The OI requests additional documentation or clarification from the OC.
- If the OC does not respond within the timeframe defined in the contract, the OI may mark the ticket as resolved with a specific reason.
resolved: The OI completes the ticket and waits for OC validation.
- The OC can either accept or reject the resolution.
- If the OC takes no action within the contractual timeframe, the OI will automatically close the ticket.
Resolution Reasons (StatusChangeReason):
- DELAY_ANSWER_EXPIRED: The OC failed to provide additional information within the timeframe.
- RESOLVED: Ticket successfully resolved.
- UNRESOLVABLE: Ticket could not be resolved. The OI will specify the reason in the ticket.
canceled: The ticket is canceled by the OC.
- The OC can cancel the ticket at any point if the creation or modification request is no longer required.
closed: The ticket is finalized and validated.
Closure may occur if the OC validates the resolution or if the OC fails to respond within the contractual validation period. The StatusChangeReason provides the closure justification:
- DELAY_VALIDATION_EXPIRED: Validation timeframe exceeded.
- RESOLUTION_ACCEPTED: Ticket resolution accepted by the OC. No further actions are permitted once the ticket reaches this state.
Permissible Status Transitions Note:
The protocol does not impose a limit on the number of resolution rejections by the OC. In the resolved state, automatic ticket closure occurs if the OC neither accepts nor rejects the resolution within a reasonable timeframe defined in the contracts.
Reasons for Status Changes reason-status-changes
Error codes error-codes
Errors
Important
Failure to code a proper management of the error responses in your application may affect its resilience. Access to the API may be revoked if your application generates too many mishandled errors.
Your application must parse the returned HTTP response to check if an error is returned instead of a 200 OK. Orange APIs use appropriate HTTP status codes to indicate any request processing error, providing detailed information about the underlying fault. This helps you provide better feedback to your users and implement failure recovery mechanisms in your application.
For details on the main error codes, response format, tips and troubleshooting, see our Handling API errors guide
Errors 401
If you get a status code 401 with the error code 42 (such as below), then request a new access token.
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"code": 42,
"message": "Expired credentials",
"description": "The requested service needs credentials, and the ones provided
were out-of-date."
}
Important
- Each
access_tokenhas a lifetime validity period. This validity period may change overtime to comply with security rules.- The token server has a maximum hourly quota per client application to prevent from misuse.
Therefore,
DON'T request anaccess_tokeneach time you invoke the service API.
DON'T hard-code a validity duration in your application.
Instead, your application must parse the returned status code and error code to check if it needs to request a newaccess token.
For other 401 errors: check that you provide the right Autorization header with the right Bearer
Errors 400
In case of invalid request to the API, you will receive a 400 error code with detailed information in the body message, such as:
HTTP/1.1 400 Bad Request
{
"code": 25,
"description": "Missing header",
"message": "...."
}