# Provider export NDJSON consumer example The provider export endpoint returns `application/x-ndjson`. NDJSON is newline-delimited JSON: each non-empty line is a complete `ProviderExportResponse` JSON object. Clients should read and process the response one line at a time instead of trying to deserialize the whole response as a JSON array. For a successful provider match, each response line currently contains one provider in `MatchingProviderRecords`. Validation failures and searches with no matches are also returned as an NDJSON line with `ErrorMessage` populated. These application-level errors are returned in a `200 OK` response, so consumers must inspect `ErrorMessage` as well as the HTTP status. ```http GET https://example.com/api/providers?UKPRNStatus=active&UpdatedSince=2026-01-01T00:00:00Z Accept: application/x-ndjson ``` To filter by more than one UKPRN, repeat the query parameter: ```http GET https://example.com/api/providers?UKPRNS=10000001&UKPRNS=10000002 Accept: application/x-ndjson ``` ## C# streaming consumer ```csharp using System.Net.Http.Headers; using System.Text.Json; var client = new HttpClient { BaseAddress = new Uri("https://example.com/") }; using var request = new HttpRequestMessage( HttpMethod.Get, "api/providers?UKPRNStatus=active&UpdatedSince=2026-01-01T00:00:00Z"); request.Headers.Accept.Add( new MediaTypeWithQualityHeaderValue("application/x-ndjson")); using var response = await client.SendAsync( request, HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); await using var stream = await response.Content.ReadAsStreamAsync(); using var reader = new StreamReader(stream); while (await reader.ReadLineAsync() is { } line) { if (string.IsNullOrWhiteSpace(line)) { continue; } var exportResponse = JsonSerializer.Deserialize( line, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); if (!string.IsNullOrWhiteSpace(exportResponse?.ErrorMessage)) { Console.Error.WriteLine(exportResponse.ErrorMessage); continue; } foreach (var provider in exportResponse?.MatchingProviderRecords ?? []) { Console.WriteLine($"{provider.UKPRN}: {provider.ProviderName}"); Console.WriteLine($"Status: {provider.ProviderStatus}"); Console.WriteLine($"Last updated: {provider.LastUpdated:O}"); Console.WriteLine($"Primary contact email: {provider.PrimaryContact?.ContactEmail}"); Console.WriteLine($"Primary contact URL: {provider.PrimaryContact?.Url}"); } } public sealed class ProviderExportResponse { public string? ErrorMessage { get; set; } public List MatchingProviderRecords { get; set; } = []; } public sealed class ProviderRecord { public string? UKPRN { get; set; } public string? ProviderName { get; set; } public string? ProviderStatus { get; set; } public DateTime? VerificationDate { get; set; } public DateTime? LastUpdated { get; set; } public string? ICOReference { get; set; } public bool? SoleTrader { get; set; } public ProviderAddress? LegalAddress { get; set; } public List TradingAddresses { get; set; } = []; public ProviderContact? PrimaryContact { get; set; } public List ProviderAliases { get; set; } = []; public List VerificationDetails { get; set; } = []; } public sealed class ProviderAddress { public string? AddressType { get; set; } public string? Address1 { get; set; } public string? Address2 { get; set; } public string? Address3 { get; set; } public string? Address4 { get; set; } public string? Town { get; set; } public string? County { get; set; } public string? Postcode { get; set; } } public sealed class ProviderContact { public ContactPersonalDetails? ContactPersonalDetails { get; set; } public string? ContactRole { get; set; } public string? ContactTelephone1 { get; set; } public string? ContactTelephone2 { get; set; } public string? ContactEmail { get; set; } public string? Url { get; set; } } public sealed class ContactPersonalDetails { public string? PersonNameTitle { get; set; } public string? PersonGivenName { get; set; } public string? PersonFamilyName { get; set; } } public sealed class TradingName { public string? Name { get; set; } } public sealed class VerificationDetails { public string? VerificationAuthority { get; set; } public string? VerificationID { get; set; } public bool PrimaryVerificationSource { get; set; } } ``` Notes for client implementations: - The response is not a JSON array; parse each non-empty line independently. - A normal response line currently contains one item in `MatchingProviderRecords`. - Check `ErrorMessage` on every line, even after receiving a successful HTTP status. - `ProviderStatus` is returned as `active` or `deactivated`. - `PrimaryContact.Url` is returned as an empty string when no website address is available. - `PageNumber` defaults to 1 when paging is requested. `PageSize` defaults to 500 and is capped at 5,000.