Column headers are matched exactly, and letter case matters. A header that is misspelled or cased differently is not reported as an error. The column is read as empty instead, and the file is processed as though you had sent no value at all. Check your header row against the template above before every upload.
The upload checks the content type, not the file extension. A workbook sent with a spreadsheet content type is accepted at upload and then fails later during processing, because the file is always read as CSV. Export to CSV before uploading.
Quote any value that contains a comma, such as a room description, so that it is not read as two columns.
Save the file as UTF-8 so that accented characters in room names survive. No encoding is enforced, so a file saved in another encoding is accepted and may produce mangled room names.
Leave a column empty when you have no value for it. Literal text such as NULL or null is treated as a value rather than as an empty cell.
Do not insert values in JSON or array format, and do not include HTML markup.
Do not include rate plan codes in the RoomCode column.
Provider values are compared exactly, and case sensitively, against the provider list your account is entitled to. A file containing a provider your account is not authorised for is refused, and the message lists the unrecognised names. Note that this refusal is returned in the response body with an HTTP 200 status and no status code, so check the body rather than the HTTP status. The message is also always prefixed with the mandatory fields wording, even when an unauthorised provider is the only fault.
The file based path and the API paths check provider against two different account scoped lists. A provider accepted in a file upload can still be rejected with status code 1011 on the real time or asynchronous path, and the reverse is also possible. Verify a provider on the path you intend to use rather than assuming one result carries over.
Mandatory values are checked across the whole file rather than row by row. If any row has an empty Provider, ProviderHotelId or RoomName, the entire file is rejected and the message names the column, not the row, so correct every occurrence before resubmitting.
100,000 rooms are processed per batch by default. Records beyond this limit are skipped automatically and the run still finishes with status Completed, so always compare the row count of your output file against your input file.
A Completed status does not by itself guarantee an output file. If the run succeeds but uploading the output fails, the status still reads Completed. Treat a missing output file as a run to raise with support rather than as an empty result.
For volumes above the 10 MB upload limit, use the SFTP based submission instead. Contact the Vervotech mappings team to have it configured.
GroupId is not a durable key. The part after the hotel ID is a counter assigned within a single run, in the order the groups happened to be produced. Re-running the same file can give the same room a different GroupId. Do not persist it as a join key; join on the supplier's own Provider and RoomCode instead.
IsExclusive can under report. It is derived from a provider set that is not always updated when groups are merged, so a group holding rates from more than one provider can still be marked exclusive. Treat it as a hint rather than a guarantee, and derive exclusivity yourself from the Provider column if it matters to you.
MappedOcccupancy is derived, not supplied. It is read out of the room name and expressed as a category, not copied from any occupancy value you sent. Unlike the occupancy fields on the input side, this one does take part in grouping.