Archive
USA Vehicle Registration API: Complete Guide to American VIN and License Plate Lookups

The United States represents one of the largest automotive markets in the world, with over 270 million registered vehicles across all 50 states. For developers and businesses working with American vehicle data, the USA Vehicle Registration API provides instant access to comprehensive vehicle information using license plate numbers and state codes. See here: https://www.vehicleregistrationapi.com/
Overview of USA Vehicle Registration System
Unlike many countries that have centralized vehicle registration systems, the United States operates on a state-by-state basis. Each of the 50 states, plus Washington D.C., Puerto Rico, Guam, and the Virgin Islands, maintains its own vehicle registration database. This decentralized approach means that vehicle lookups require both the license plate number and the state where the vehicle is registered.
USA Vehicle API Features
The USA endpoint provides access to vehicle information across all American jurisdictions, including:
Supported Jurisdictions
- All 50 States – From Alabama to Wyoming
- Federal District – Washington D.C. (DC)
- Territories – Puerto Rico (PR), Guam (GU), Virgin Islands (VI)
Data Available
When querying American vehicle registrations, you can retrieve:
- Vehicle Description – Complete make, model, and year information
- Body Style – Vehicle type classification (sedan, SUV, pickup truck, etc.)
- VIN Number – Complete 17-character Vehicle Identification Number
- Engine Specifications – Engine size and configuration details
- Country of Assembly – Where the vehicle was manufactured
- Registration Year – Year the vehicle was first registered
API Implementation
Endpoint Usage
The USA Vehicle Registration API uses the /CheckUSA endpoint and requires two parameters:
- License Plate Number – The registration number (without spaces or special characters)
- State Code – Two-letter abbreviation for the state of registration
State Codes Reference
The API accepts standard two-letter state abbreviations:
States A-M:
- AL (Alabama), AK (Alaska), AZ (Arizona), AR (Arkansas)
- CA (California), CO (Colorado), CT (Connecticut), DE (Delaware)
- FL (Florida), GA (Georgia), HI (Hawaii), ID (Idaho)
- IL (Illinois), IN (Indiana), IA (Iowa), KS (Kansas)
- KY (Kentucky), LA (Louisiana), ME (Maine), MD (Maryland)
- MA (Massachusetts), MI (Michigan), MN (Minnesota), MS (Mississippi), MO (Missouri), MT (Montana)
States N-W:
- NE (Nebraska), NV (Nevada), NH (New Hampshire), NJ (New Jersey)
- NM (New Mexico), NY (New York), NC (North Carolina), ND (North Dakota)
- OH (Ohio), OK (Oklahoma), OR (Oregon), PA (Pennsylvania)
- RI (Rhode Island), SC (South Carolina), SD (South Dakota), TN (Tennessee)
- TX (Texas), UT (Utah), VT (Vermont), VA (Virginia)
- WA (Washington), WV (West Virginia), WI (Wisconsin), WY (Wyoming)
Federal & Territories:
- DC (District of Columbia), GU (Guam), PR (Puerto Rico), VI (Virgin Islands)
Sample Implementation
Basic API Call Example
// JavaScript example for USA vehicle lookup
const username = 'your_api_username';
const plateNumber = 'ABC1234';
const state = 'CA'; // California
const apiUrl = `https://www.regcheck.org.uk/api/reg.asmx/CheckUSA?RegistrationNumber=${plateNumber}&State=${state}&username=${username}`;
fetch(apiUrl)
.then(response => response.text())
.then(data => {
// Parse XML response
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(data, "text/xml");
const jsonData = xmlDoc.getElementsByTagName("vehicleJson")[0].textContent;
const vehicleInfo = JSON.parse(jsonData);
console.log("Vehicle:", vehicleInfo.Description);
console.log("VIN:", vehicleInfo.VechileIdentificationNumber);
console.log("Body Style:", vehicleInfo.BodyStyle.CurrentTextValue);
})
.catch(error => console.error('Error:', error));
Response Format
The API returns data in both XML and JSON formats. Here’s a sample response for a 2004 Dodge Durango:
{
"Description": "2004 Dodge Durango Limited",
"BodyStyle": {
"CurrentTextValue": "SUV 4D"
},
"VechileIdentificationNumber": "1D8HB58D04F177301",
"Assembly": "United States",
"EngineSize": {
"CurrentTextValue": "5.7L V8 MPI"
},
"RegistrationYear": "2004",
"CarMake": {
"CurrentTextValue": "Dodge"
},
"CarModel": {
"CurrentTextValue": "Durango Limited"
},
"MakeDescription": {
"CurrentTextValue": "Dodge"
},
"ModelDescription": {
"CurrentTextValue": "Durango Limited"
}
}
State-Specific Considerations
California (CA)
California has one of the most comprehensive vehicle databases in the US, with detailed information available for most vehicles. The state’s emissions requirements mean additional environmental data may be available.
Texas (TX)
As the second-largest state by population and vehicle registrations, Texas maintains extensive records. The state’s diverse automotive market includes everything from pickup trucks to luxury vehicles.
Florida (FL)
Florida’s high volume of vehicle imports and exports, combined with its large retiree population, creates a unique mix of vehicle types and registration patterns.
New York (NY)
New York’s database includes both upstate rural vehicles and New York City urban registrations, providing a diverse dataset for vehicle information.
Use Cases for USA Vehicle API
Insurance Industry Applications
- Policy Underwriting – Verify vehicle specifications for accurate premium calculations
- Claims Processing – Validate vehicle information during accident claims
- Fraud Prevention – Cross-reference vehicle details to detect inconsistencies
Automotive Dealers
- Inventory Management – Automatically populate vehicle listings with accurate specifications
- Trade-In Valuations – Verify vehicle details for pricing assessments
- Sales Documentation – Ensure accurate vehicle information on sales contracts
Fleet Management
- Asset Tracking – Maintain detailed records of company vehicle fleets
- Compliance Monitoring – Verify vehicle specifications for regulatory compliance
- Maintenance Scheduling – Access manufacturer specifications for service intervals
Law Enforcement
- Vehicle Identification – Quick lookup for traffic stops and investigations
- Asset Recovery – Verify vehicle ownership and specifications
- Investigation Support – Cross-reference vehicle data in criminal cases
Mobile Applications
- Car Shopping Apps – Instant vehicle specification lookup for used car buyers
- Maintenance Apps – Access vehicle specs for service reminders and parts ordering
- Insurance Apps – Quick vehicle verification for policy quotes
Integration Best Practices
Error Handling
Always implement robust error handling when working with the USA API:
import requests
import xml.etree.ElementTree as ET
import json
def lookup_usa_vehicle(plate_number, state, username):
try:
url = f"https://www.regcheck.org.uk/api/reg.asmx/CheckUSA"
params = {
'RegistrationNumber': plate_number,
'State': state,
'username': username
}
response = requests.get(url, params=params)
response.raise_for_status()
# Parse XML response
root = ET.fromstring(response.content)
json_data = root.find('.//vehicleJson').text
if json_data:
vehicle_data = json.loads(json_data)
return vehicle_data
else:
return {"error": "No vehicle data found"}
except requests.RequestException as e:
return {"error": f"API request failed: {str(e)}"}
except ET.ParseError as e:
return {"error": f"XML parsing failed: {str(e)}"}
except json.JSONDecodeError as e:
return {"error": f"JSON parsing failed: {str(e)}"}
# Usage example
result = lookup_usa_vehicle("ABC1234", "CA", "your_username")
print(result)
Rate Limiting and Credits
The USA Vehicle API operates on a credit-based system:
- Each successful lookup consumes one credit
- Failed lookups (no data found) typically don’t consume credits
- Monitor your credit balance to avoid service interruptions
- Consider implementing local caching for frequently accessed data
Data Validation
Before making API calls, validate input parameters:
function validateUSALookup(plateNumber, state) {
// Valid US state codes
const validStates = [
'AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'FL', 'GA',
'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MD',
'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NJ',
'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC',
'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY',
'DC', 'GU', 'PR', 'VI'
];
if (!plateNumber || plateNumber.length < 2 || plateNumber.length > 8) {
return { valid: false, error: "Invalid plate number length" };
}
if (!validStates.includes(state.toUpperCase())) {
return { valid: false, error: "Invalid state code" };
}
return { valid: true };
}
Limitations and Coverage
Data Availability
- Coverage varies by state based on data sharing agreements
- Some states may have limited historical data
- Newer registrations typically have more complete information
- Commercial vehicles may have different data availability
Privacy Considerations
- The API provides vehicle specifications, not personal owner information
- All data returned is from publicly available vehicle registration records
- Comply with local privacy laws when storing or processing vehicle data
- Consider data retention policies for cached information
Getting Started
Account Setup
- Create Account – Register at regcheck.org.uk for API access
- Email Verification – Confirm your email to receive free test credits
- Test the Service – Use provided sample license plates for testing
- Purchase Credits – Buy additional credits for production use
Testing with Sample Data
Use this sample license plate for testing: ZZZ9999 with state NC (North Carolina)
This will return information about a 2004 Dodge Durango Limited without consuming your credits.
Pricing and Support
Credit Costs
- Standard rate: 1 credit per successful vehicle lookup
- Volume discounts available for high-usage applications
- Failed lookups typically don’t consume credits
Technical Support
- API documentation available at regcheck.org.uk
- Email support for technical integration questions
- WSDL definition available for SOAP implementations
Conclusion
The USA Vehicle Registration API provides comprehensive access to American vehicle data across all 50 states and territories. With proper implementation and error handling, developers can integrate reliable vehicle lookup functionality into their applications, supporting use cases from insurance processing to mobile app development.
The decentralized nature of American vehicle registration creates unique challenges, but the API abstracts this complexity, providing a single endpoint for nationwide vehicle data access. Whether you’re building consumer applications or enterprise solutions, the USA Vehicle Registration API offers the reliability and coverage needed for professional vehicle data integration.
Ready to start integrating American vehicle data into your application? Sign up for your free API account today and begin exploring the extensive database of US vehicle registrations.
Complete Guide to the UK Vehicle Registration #API: Access #DVLA Data, #MOT History, and More

Are you developing an application that needs instant access to UK vehicle information? The UK Vehicle Registration API provides comprehensive access to DVLA data, MOT history, tax information, and vehicle specifications through a simple integration. This powerful tool allows developers to retrieve detailed vehicle information using just a Vehicle Registration Mark (VRM). Here: https://regcheck.org.uk/
What is the UK Vehicle Registration API?
The UK Vehicle Registration API is a SOAP-based web service that provides instant access to official UK vehicle data. By simply entering a vehicle registration number (VRM), you can retrieve comprehensive information about cars, motorcycles, and commercial vehicles registered with the DVLA.
Key Features:
- Instant VRM lookups for all UK-registered vehicles
- Complete MOT history with test results and failure reasons
- Tax status information including expiry dates
- Comprehensive vehicle specifications including make, model, engine details
- Support for special territories including Isle of Man and Jersey
- Both XML and JSON response formats
UK Vehicle Data Available
Standard Vehicle Information
When you query the UK endpoint using a vehicle registration number, you’ll receive:
- Make and Model – Manufacturer and specific vehicle model
- Year of Registration – When the vehicle was first registered
- VIN Number – Complete Vehicle Identification Number
- ABI Code – Association of British Insurers classification code
- Body Style – Vehicle type (saloon, hatchback, SUV, etc.)
- Engine Size – Displacement in cubic centimeters
- Number of Doors – Vehicle door configuration
- Transmission Type – Manual or automatic
- Fuel Type – Petrol, diesel, electric, hybrid
- Immobiliser Status – Security system information
- Number of Seats – Seating capacity
- Driver Side – Left or right-hand drive
- Vehicle Color – Primary exterior color
Example Response for UK Vehicle Data
{
"ABICode": "32130768",
"Description": "MERCEDES-BENZ E220 SE CDI",
"RegistrationYear": "2013",
"CarMake": {
"CurrentTextValue": "MERCEDES-BENZ"
},
"CarModel": {
"CurrentTextValue": "E220 SE CDI"
},
"EngineSize": {
"CurrentTextValue": "2143"
},
"FuelType": {
"CurrentTextValue": "Diesel"
},
"Transmission": {
"CurrentTextValue": "Automatic"
},
"NumberOfDoors": {
"CurrentTextValue": "4DR"
},
"BodyStyle": {
"CurrentTextValue": "Saloon"
},
"Colour": "WHITE",
"VehicleIdentificationNumber": "WDD2120022A899877"
}
MOT History API – Complete Test Records
One of the most valuable features of the UK Vehicle API is access to complete MOT history data. This service covers all UK cars (excluding Northern Ireland) and provides detailed test information including:
MOT Data Includes:
- Test Date – When each MOT was conducted
- Test Result – Pass or Fail status
- Odometer Reading – Mileage at time of test
- Test Number – Official MOT test reference
- Failure Reasons – Detailed list of any failures
- Advisory Notes – Items that need attention
- Expiry Date – When the MOT certificate expires
MOT History Response Example
[
{
"TestDate": "8 November 2016",
"ExpiryDate": "16 November 2017",
"Result": "Pass",
"Odometer": "61,706 miles",
"TestNumber": "2754 6884 4000",
"FailureReasons": [],
"Advisories": []
},
{
"TestDate": "8 November 2016",
"Result": "Fail",
"Odometer": "61,703 miles",
"TestNumber": "5901 3690 4542",
"FailureReasons": [
"Nearside Rear Brake pipe excessively corroded (3.6.B.2c)",
"Offside Rear Brake pipe excessively corroded (3.6.B.2c)"
],
"Advisories": []
}
]
Extended Vehicle Information with Tax Data
The API also provides enhanced vehicle information including tax and emissions data:
- Make and Registration Date
- Year of Manufacture
- CO2 Emissions – Environmental impact rating
- Tax Status – Current road tax status
- Tax Due Date – When road tax expires
- Vehicle Type Approval – EU approval classification
- Wheelplan – Axle configuration
- Weight Information – Gross vehicle weight
UK Motorcycle Support
For motorcycles registered in the UK, use the dedicated CheckMotorBikeUK endpoint. This returns motorcycle-specific information:
- Make and Model – Manufacturer and bike model
- Year of Registration
- Engine Size – Engine displacement
- Variant – Specific model variant
- Colour – Primary color
- VIN – Complete chassis number
- Engine Number – Engine identification
Motorcycle Response Example
{
"Description": "HONDA ST1300 A",
"RegistrationYear": "2005",
"CarMake": {
"CurrentTextValue": "HONDA"
},
"CarModel": {
"CurrentTextValue": "ST1300 A"
},
"EngineSize": {
"CurrentTextValue": "1261"
},
"BodyStyle": {
"CurrentTextValue": "Motorbike"
},
"FuelType": {
"CurrentTextValue": "PETROL"
},
"Colour": "YELLOW",
"VehicleIdentificationNumber": "JH2SC51A92M007472"
}
Isle of Man Vehicle Support
Vehicles registered in the Isle of Man (identified by “MN”, “MAN”, or “MANX” in the registration) return enhanced data including:
- Standard vehicle information (make, model, engine size)
- Version details – Specific trim level
- CO2 emissions – Environmental data
- Tax status – “Active” or expired
- Tax expiry date – When road tax is due
- Wheelplan – Vehicle configuration
Isle of Man Response Example
{
"Description": "HONDA JAZZ",
"RegistrationYear": 2012,
"CarMake": {
"CurrentTextValue": "HONDA"
},
"Version": "I-VTEC ES",
"Colour": "SILVER",
"Co2": "126",
"RegistrationDate": "06/07/2012",
"WheelPlan": "2-AXLE Rigid",
"Taxed": "Active",
"TaxExpiry": "31/07/2018"
}
Integration and Implementation
API Endpoint
The service is available at: https://www.regcheck.org.uk/api/reg.asmx
WSDL Definition
Access the service definition at: https://www.regcheck.org.uk/api/reg.asmx?wsdl
Authentication
All API calls require a valid username. You can obtain a test account with 10 free credits after email verification.
Sample Implementation (PHP)
<?php
$username = 'Your_Username_Here';
$regNumber = 'AB12CDE';
$xmlData = file_get_contents("https://www.regcheck.org.uk/api/reg.asmx/Check?RegistrationNumber=" . $regNumber . "&username=" . $username);
$xml = simplexml_load_string($xmlData);
$strJson = $xml->vehicleJson;
$json = json_decode($strJson);
echo "Vehicle: " . $json->Description;
echo "Year: " . $json->RegistrationYear;
echo "Fuel: " . $json->FuelType->CurrentTextValue;
?>
Use Cases for UK Vehicle API
For Businesses:
- Insurance Companies – Instant vehicle verification and risk assessment
- Car Dealers – Vehicle history checks and specifications
- Fleet Management – MOT tracking and compliance monitoring
- Automotive Marketplaces – Automated vehicle data population
- Garage Services – Customer vehicle information lookup
For Developers:
- Mobile Apps – Vehicle checking applications
- Web Platforms – Integrated vehicle lookup features
- Compliance Tools – MOT and tax reminder systems
- Data Validation – Verify vehicle registration details
Benefits of Using the UK Vehicle Registration API
- Official DVLA Data – Access to authoritative government vehicle records
- Real-time Information – Instant access to current vehicle status
- Comprehensive Coverage – Supports cars, motorcycles, and commercial vehicles
- Historical Data – Complete MOT history with detailed records
- Multiple Formats – Both XML and JSON response options
- Reliable Service – High uptime and consistent performance
- Cost Effective – Credit-based pricing with free test options
Getting Started
To begin using the UK Vehicle Registration API:
- Sign up for a free test account at regcheck.org.uk
- Verify your email address to receive 10 free credits
- Test the API with sample vehicle registration numbers
- Purchase additional credits as needed for production use
- Implement the API in your application using provided documentation
Security and Compliance
The API includes several security features:
- IP Address Restrictions – Lock access to specific IP addresses
- Credit Monitoring – Balance alerts and daily usage limits
- Secure Connections – HTTPS encryption for all API calls
- Data Protection – Compliance with UK data protection regulations
Conclusion
The UK Vehicle Registration API provides developers and businesses with comprehensive access to official DVLA data, MOT records, and vehicle specifications. Whether you’re building a consumer app for vehicle checks or integrating vehicle data into business systems, this API offers the reliability and data coverage needed for professional applications.
With support for standard UK vehicles, motorcycles, and special territories like the Isle of Man, plus detailed MOT history and tax information, the UK Vehicle Registration API is the most complete solution for accessing UK vehicle data programmatically.
Ready to get started? Visit the RegCheck website to create your free account and begin exploring UK vehicle data today.
Porting a PHP OAuth Spotler Client to C#: Lessons Learned
Recently I had to integrate with Spotler’s REST API from a .NET application. Spotler provides a powerful marketing automation platform, and their API uses OAuth 1.0 HMAC-SHA1 signatures for authentication.
They provided a working PHP client, but I needed to port this to C#. Here’s what I learned (and how you can avoid some common pitfalls).
🚀 The Goal
We started with a PHP class that:
✅ Initializes with:
consumerKeyconsumerSecret- optional SSL certificate verification
✅ Creates properly signed OAuth 1.0 requests
✅ Makes HTTP requests with cURL and parses the JSON responses.
I needed to replicate this in C# so we could use it inside a modern .NET microservice.
🛠 The Port to C#
🔑 The tricky part: OAuth 1.0 signatures
Spotler’s API requires a specific signature format. It’s critical to:
- Build the signature base string by concatenating:
- The uppercase HTTP method (e.g.,
GET), - The URL-encoded endpoint,
- And the URL-encoded, sorted OAuth parameters.
- The uppercase HTTP method (e.g.,
- Sign it using HMAC-SHA1 with the
consumerSecretfollowed by&. - Base64 encode the HMAC hash.
This looks simple on paper, but tiny differences in escaping or parameter order will cause 401 Unauthorized.
💻 The final C# solution
We used HttpClient for HTTP requests, and HMACSHA1 from System.Security.Cryptography for signatures. Here’s what our C# SpotlerClient does:
✅ Generates the OAuth parameters (consumer_key, nonce, timestamp, etc).
✅ Creates the exact signature base string, matching the PHP implementation character-for-character.
✅ Computes the HMAC-SHA1 signature and Base64 encodes it.
✅ Builds the Authorization header.
✅ Sends the HTTP request, with JSON bodies if needed.
We also added better exception handling: if the API returns an error (like 401), we throw an exception that includes the full response body. This made debugging much faster.
🐛 Debugging tips for OAuth 1.0
- Print the signature base string.
It needs to match exactly what Spotler expects. Any stray spaces or wrong escaping will fail. - Double-check timestamp and nonce generation.
OAuth requires these to prevent replay attacks. - Compare with the PHP implementation.
We literally copied the signature generation line-by-line from PHP into C#, carefully mappingrawurlencodetoUri.EscapeDataString. - Turn off SSL validation carefully.
During development, you might disable certificate checks (ServerCertificateCustomValidationCallback), but never do this in production.
using System.Security.Cryptography;
using System.Text;
namespace SpotlerClient
{
public class SpotlerClient
{
private readonly string _consumerKey;
private readonly string _consumerSecret;
private readonly string _baseUrl = "https://restapi.mailplus.nl";
private readonly HttpClient _httpClient;
public SpotlerClient(string consumerKey, string consumerSecret, bool verifyCertificate = true)
{
_consumerKey = consumerKey;
_consumerSecret = consumerSecret;
var handler = new HttpClientHandler();
if (!verifyCertificate)
{
handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
}
_httpClient = new HttpClient(handler);
}
public async Task<string> ExecuteAsync(string endpoint, HttpMethod method, string jsonData = null)
{
var request = new HttpRequestMessage(method, $"{_baseUrl}/{endpoint}");
var authHeader = CreateAuthorizationHeader(method.Method, endpoint);
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Authorization", authHeader);
if (jsonData != null)
{
request.Content = new StringContent(jsonData, Encoding.UTF8, "application/json");
}
var response = await _httpClient.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
var body = await response.Content.ReadAsStringAsync();
return body;
}
return await response.Content.ReadAsStringAsync();
}
private string CreateAuthorizationHeader(string httpMethod, string endpoint)
{
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
var nonce = Guid.NewGuid().ToString("N");
var paramString = "oauth_consumer_key=" + Uri.EscapeDataString(_consumerKey) +
"&oauth_nonce=" + Uri.EscapeDataString(nonce) +
"&oauth_signature_method=" + Uri.EscapeDataString("HMAC-SHA1") +
"&oauth_timestamp=" + Uri.EscapeDataString(timestamp) +
"&oauth_version=" + Uri.EscapeDataString("1.0");
var sigBase = httpMethod.ToUpper() + "&" +
Uri.EscapeDataString(_baseUrl + "/" + endpoint) + "&" +
Uri.EscapeDataString(paramString);
var sigKey = _consumerSecret + "&";
var signature = ComputeHmacSha1Signature(sigBase, sigKey);
var authHeader = $"OAuth oauth_consumer_key=\"{_consumerKey}\", " +
$"oauth_nonce=\"{nonce}\", " +
$"oauth_signature_method=\"HMAC-SHA1\", " +
$"oauth_timestamp=\"{timestamp}\", " +
$"oauth_version=\"1.0\", " +
$"oauth_signature=\"{Uri.EscapeDataString(signature)}\"";
return authHeader;
}
private string ComputeHmacSha1Signature(string data, string key)
{
using var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(key));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
return Convert.ToBase64String(hash);
}
}
}
✅ The payoff
Once the signature was constructed precisely, authentication errors disappeared. We could now use the Spotler REST API seamlessly from C#, including:
- importing contact lists,
- starting campaigns,
- and fetching campaign metrics.
📚 Sample usage
var client = new SpotlerClient(_consumerKey, _consumerSecret, false);
var endpoint = "integrationservice/contact/email@gmail.com";
var json = client.ExecuteAsync(endpoint, HttpMethod.Get).GetAwaiter().GetResult();
🎉 Conclusion
Porting from PHP to C# isn’t always as direct as it looks — especially when it comes to cryptographic signatures. But with careful attention to detail and lots of testing, we managed to build a robust, reusable client.
If you’re facing a similar integration, feel free to reach out or clone this approach. Happy coding!
🚫 Why AWS SDK for S3 No Longer Works Smoothly with .NET Framework 4.8 — and How to Fix It
In 2024, more .NET developers are finding themselves in a strange situation: suddenly, tried-and-tested .NET Framework 4.8 applications that interact with Amazon S3 start throwing cryptic build errors or runtime exceptions. The culprit? The AWS SDK for .NET has increasingly shifted toward support for .NET Core / .NET 6+, and full compatibility with .NET Framework is eroding.
In this post, we’ll explain:
- Why this happens
- What errors you might see
- And how to remove the AWS SDK altogether and replace it with pure .NET 4.8-compatible code for downloading (and uploading) files from S3 using Signature Version 4.
🧨 The Problem: AWS SDK & .NET Framework 4.8
The AWS SDK for .NET (like AWSSDK.S3) now depends on modern libraries like:
System.Text.JsonSystem.BuffersSystem.Runtime.CompilerServices.UnsafeMicrosoft.Bcl.AsyncInterfaces
These dependencies were designed for .NET Core and later versions — not .NET Framework. While it was once possible to work around this with binding redirects and careful version pinning, the situation has become unstable and error-prone.
❗ Common Symptoms
You may see errors like:
Could not load file or assembly ‘System.Text.Json, Version=6.0.0.11’
Or:
Could not load file or assembly ‘System.Buffers, Version=4.0.5.0’
Or during build:
Warning: Unable to update auto-refresh reference ‘system.text.json.dll’
Even if you install the correct packages, you may end up needing to fight bindingRedirect hell, and still not get a working application.
✅ The Solution: Remove the AWS SDK
Fortunately, you don’t need the SDK to use S3. All AWS S3 requires is a properly signed HTTP request using AWS Signature Version 4, and you can create that yourself using standard .NET 4.8 libraries.
🔐 Downloading from S3 Without the AWS SDK
Here’s how you can download a file from S3 using HttpWebRequest and Signature Version 4.
✔️ The Key Points:
- You must include the
x-amz-content-sha256header (even for GETs!) - You sign the request using your AWS secret key
- No external packages required — works on plain .NET 4.8
🧩 Code Snippet
public static byte[] DownloadFromS3(string bucketName, string objectKey, string region, string accessKey, string secretKey)
{
var method = "GET";
var service = "s3";
var host = $"{bucketName}.s3.{region}.amazonaws.com";
var uri = $"https://{host}/{objectKey}";
var requestDate = DateTime.UtcNow;
var amzDate = requestDate.ToString("yyyyMMddTHHmmssZ");
var dateStamp = requestDate.ToString("yyyyMMdd");
var canonicalUri = "/" + objectKey;
var signedHeaders = "host;x-amz-content-sha256;x-amz-date";
var payloadHash = HashSHA256(string.Empty); // Required even for GET
var canonicalRequest = $"{method}\n{canonicalUri}\n\nhost:{host}\nx-amz-content-sha256:{payloadHash}\nx-amz-date:{amzDate}\n\n{signedHeaders}\n{payloadHash}";
var credentialScope = $"{dateStamp}/{region}/{service}/aws4_request";
var stringToSign = $"AWS4-HMAC-SHA256\n{amzDate}\n{credentialScope}\n{HashSHA256(canonicalRequest)}";
var signingKey = GetSignatureKey(secretKey, dateStamp, region, service);
var signature = ToHexString(HmacSHA256(signingKey, stringToSign));
var authorizationHeader = $"AWS4-HMAC-SHA256 Credential={accessKey}/{credentialScope}, SignedHeaders={signedHeaders}, Signature={signature}";
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = method;
request.Headers["Authorization"] = authorizationHeader;
request.Headers["x-amz-date"] = amzDate;
request.Headers["x-amz-content-sha256"] = payloadHash;
try
{
using (var response = (HttpWebResponse)request.GetResponse())
using (var responseStream = response.GetResponseStream())
using (var memoryStream = new MemoryStream())
{
responseStream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
catch (WebException ex)
{
using (var errorResponse = (HttpWebResponse)ex.Response)
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
var errorText = reader.ReadToEnd();
throw new Exception($"S3 request failed: {errorText}", ex);
}
}
}
🔧 Supporting Methods
private static string HashSHA256(string text)
{
using (var sha256 = SHA256.Create())
{
return ToHexString(sha256.ComputeHash(Encoding.UTF8.GetBytes(text)));
}
}
private static byte[] HmacSHA256(byte[] key, string data)
{
using (var hmac = new HMACSHA256(key))
{
return hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
}
}
private static byte[] GetSignatureKey(string secretKey, string dateStamp, string region, string service)
{
var kSecret = Encoding.UTF8.GetBytes("AWS4" + secretKey);
var kDate = HmacSHA256(kSecret, dateStamp);
var kRegion = HmacSHA256(kDate, region);
var kService = HmacSHA256(kRegion, service);
return HmacSHA256(kService, "aws4_request");
}
private static string ToHexString(byte[] bytes)
{
return BitConverter.ToString(bytes).Replace("-", "").ToLowerInvariant();
}
📝 Uploading to S3 Without the AWS SDK
You can extend the same technique for PUT requests. The only differences are:
You calculate the SHA-256 hash of the file content
You include a Content-Type and Content-Length header
You use PUT instead of GET
Let me know in the comments if you’d like the full upload version — it follows the same Signature V4 pattern.
✅ Summary
Feature AWS SDK for .NET Manual Signature V4
.NET Framework 4.8 support ❌ Increasingly broken ✅ Fully supported
Heavy NuGet dependencies ✅ ❌ Minimal
Simple download/upload ✅ ✅ (with more code)
Presigned URLs ✅ 🟡 Manual support
Final Thoughts
If you’re stuck on .NET Framework 4.8 and running into weird AWS SDK issues — you’re not alone. But you’re not stuck either. Dropping the SDK and using HTTP + Signature V4 is entirely viable, especially for simple tasks like uploading/downloading S3 files.
Let me know if you’d like a full upload example, presigned URL generator, or if you’re considering migrating to .NET 6+.
How to Query #LinkedIn from an #Email Address Using AvatarAPI.com

Introduction
When working with professional networking data, LinkedIn is often the go-to platform for retrieving user information based on an email address. Using AvatarAPI.com, developers can easily query LinkedIn and other data providers through a simple API request. In this guide, we’ll explore how to use the API to retrieve LinkedIn profile details from an email address.
API Endpoint
To query LinkedIn using AvatarAPI.com, send a request to:
https://avatarapi.com/v2/api.aspx
JSON Payload
A sample JSON request to query LinkedIn using an email address looks like this:
{
"username": "demo",
"password": "demo___",
"provider": "LinkedIn",
"email": "jason.smith@gmail.com"
}
Explanation of Parameters:
- username: Your AvatarAPI.com username.
- password: Your AvatarAPI.com password.
- provider: The data source to query. In this case, “LinkedIn” is specified. If omitted, the API will search a default set of providers.
- email: The email address for which LinkedIn profile data is being requested.
API Response
A successful response from the API may look like this:
{
"Name": "Jason Smith",
"Image": "https://media.licdn.com/dms/image/D4E12AQEud3Ll5MI7cQ/article-inline_image-shrink_1500_2232/0/1660833954461?e=1716422400&v=beta&t=r-9LmmNBpvS4bUiL6k-egJ8wUIpEeEMl9NJuAt7pTsc",
"Valid": true,
"City": "Los Angeles, California, United States",
"Country": "US",
"IsDefault": false,
"Success": true,
"RawData": "{\"resultTemplate\":\"ExactMatch\",\"bound\":false,\"persons\":[{\"id\":\"urn:li:person:DgEdy8DNfhxlX15HDuxWp7k6hYP5jIlL8fqtFRN7YR4\",\"displayName\":\"Jason Smith\",\"headline\":\"Creative Co-founder at Mega Ventures\",\"summary\":\"Jason Smith Head of Design at Mega Ventures.\",\"companyName\":\"Mega Ventures\",\"location\":\"Los Angeles, California, United States\",\"linkedInUrl\":\"https://linkedin.com/in/jason-smith\",\"connectionCount\":395,\"skills\":[\"Figma (Software)\",\"Facebook\",\"Customer Service\",\"Event Planning\",\"Social Media\",\"Sales\",\"Healthcare\",\"Management\",\"Web Design\",\"JavaScript\",\"Software Development\",\"Project Management\",\"APIs\"]}]}",
"Source": {
"Name": "LinkedIn"
}
}
Explanation of Response Fields:
- Name: The full name of the LinkedIn user.
- Image: The profile image URL.
- Valid: Indicates whether the returned data is valid.
- City: The city where the user is located.
- Country: The country of residence.
- IsDefault: Indicates whether the data is a fallback/default.
- Success: Confirms if the request was successful.
- RawData: Contains additional structured data about the LinkedIn profile, including:
- LinkedIn ID: A unique identifier for the user’s LinkedIn profile.
- Display Name: The name displayed on the user’s profile.
- Headline: The professional headline, typically the current job title or a short description of expertise.
- Summary: A brief bio or description of the user’s professional background.
- Company Name: The company where the user currently works.
- Location: The geographical location of the user.
- LinkedIn Profile URL: A direct link to the user’s LinkedIn profile.
- Connection Count: The number of LinkedIn connections the user has.
- Skills: A list of skills associated with the user’s profile, such as programming languages, software expertise, or industry-specific abilities.
- Education History: Details about the user’s academic background, including universities attended, degrees earned, and fields of study.
- Employment History: Information about past and present positions, including company names, job titles, and employment dates.
- Projects and Accomplishments: Notable work the user has contributed to, certifications, publications, and other professional achievements.
- Endorsements: Skill endorsements from other LinkedIn users, showcasing credibility in specific domains.
- Source.Name: The data provider (LinkedIn in this case).
LinkedIn Rate Limiting
By default, LinkedIn queries are subject to rate limits. To bypass these limits, additional parameters can be included in the JSON request:
{
"overrideAccount": "your_override_username",
"overridePassword": "your_override_password"
}
Using these credentials allows queries to be processed without rate limiting. However, to enable this feature, you should contact AvatarAPI.com to discuss setup and access.
Conclusion
AvatarAPI.com provides a powerful way to retrieve LinkedIn profile data using just an email address. While LinkedIn is one of the available providers, the API also supports other data sources if the provider field is omitted. With proper setup, including rate-limit bypassing credentials, you can ensure seamless access to professional networking data.
For more details, visit AvatarAPI.com.
Get #GAIA ID from #Gmail using #AvatarAPI
In this blog post, we will explore how to retrieve a user’s name, profile picture, and GAIA ID from an email address using the AvatarAPI.
Introduction to AvatarAPI
AvatarAPI is a powerful tool that allows developers to fetch user information from various providers. In this example, we will focus on retrieving data from Google, but it’s important to note that AvatarAPI supports multiple providers.
Making a Request to AvatarAPI
To get started, you need to make a POST request to the AvatarAPI endpoint with the necessary parameters. Here’s a step-by-step guide:
Step 1: Endpoint and Parameters
- Endpoint:
https://avatarapi.com/v2/api.aspx - Parameters:
username: Your AvatarAPI username (e.g.,demo)password: Your AvatarAPI password (e.g.,demo___)provider: The provider from which to fetch data (e.g.,Google)email: The email address of the user (e.g.,jenny.jones@gmail.com)
Step 2: Example Request
Here’s an example of how you can structure your request:
Copy{
"username": "demo",
"password": "demo___",
"provider": "Google",
"email": "jenny.jones@gmail.com"
}
Step 3: Sending the Request
You can use tools like Postman or write a simple script in your preferred programming language to send the POST request. Below is an example using Python with the requests library:
Copyimport requests
url = "https://avatarapi.com/v2/api.aspx"
data = {
"username": "demo",
"password": "demo___",
"provider": "Google",
"email": "jenny.jones@gmail.com"
}
response = requests.post(url, json=data)
print(response.json())
Step 4: Handling the Response
If the request is successful, you will receive a JSON response containing the user’s information. Here’s an example response:
Copy{
"Name": "Jenny Jones",
"Image": "https://lh3.googleusercontent.com/a-/ALV-UjVPreEBCPw4TstEZLnavq22uceFSCS3-KjAdHgnmyUfSA9hMKk",
"Valid": true,
"City": "",
"Country": "",
"IsDefault": true,
"Success": true,
"RawData": "108545052157874609391",
"Source": {
"Name": "Google"
}
}
Understanding the Response
- Name: The full name of the user.
- Image: The URL of the user’s profile picture.
- Valid: Indicates whether the email address is valid.
- City and Country: Location information (if available).
- IsDefault: Indicates if the returned data is the default for the provider.
- Success: Indicates whether the request was successful.
- RawData: The GAIA ID, which is a unique identifier for the user.
- Source: The provider from which the data was fetched.
Other Providers
While this example focuses on Google, AvatarAPI supports other providers as well. You can explore the AvatarAPI documentation to learn more about the available providers and their specific requirements.
Conclusion
Using AvatarAPI to retrieve user information from an email address is a straightforward process. By sending a POST request with the necessary parameters, you can easily access valuable user data such as name, profile picture, and GAIA ID. This information can be instrumental in enhancing user experiences and integrating with various applications.
Stay tuned for more insights on leveraging APIs for efficient data retrieval!
Farewell #Skype. Here’s how their #API worked.
So, with the shutdown of Skype in May 2025, only two months away, there is not much need to hold on tight to our source code for the Skype API. It worked well for us for years on AvatarAPI.com
but with the imminent shutdown, their API will undoubtedly stop working as soon as Skype is shut down, and will no longer be relevant, even if the API stays active for a little while later.
In this post, we’ll take a deep dive into a C# implementation of a Skype user search feature using HTTP requests. This code interacts with Skype’s search API to fetch user profiles based on a given search parameter. We’ll break down the core functionality, security considerations, and potential improvements.
Overview of the SkypeSearch Class
The SkypeSearch class provides a static method, Search, which sends a request to Skype’s search API to retrieve user profiles. It uses an authentication token (SkypeToken) and manages retries in case of failures. Let’s explore its components in detail.
Key Features of the Implementation
- Handles API Requests Securely: The method sets various security protocols (
Ssl3,Tls,Tls11,Tls12) to ensure compatibility with Skype’s API. - Custom Headers for Authentication: It constructs an HTTP request with necessary headers, including
x-skypetoken,x-skype-client, and others. - Manages Rate Limits & Token Refresh: If the API responds with an empty result (potentially due to a
429 Too Many Requestserror), the token is refreshed, and the search is retried up to five times. - Enhances API Response: The method modifies the API response to include an additional
avatarImageUrlfield for each result.
Breaking Down the Search Method
Constructing the API Request
var requestNumber = new Random().Next(100000, 999999);
var url = string.Format(
"https://search.skype.com/v2.0/search?searchString={0}&requestId={1}&locale=en-GB&sessionId={2}",
searchParameter, requestNumber, Guid.NewGuid());
This snippet constructs the API request URL with dynamic query parameters, including:
searchString: The user input for searching Skype profiles.requestId: A randomly generated request ID for uniqueness.sessionId: A newly generated GUID for session tracking.
Setting HTTP Headers
HTTPHeaderHandler wicket = nvc =>
{
var nvcSArgs = new NameValueCollection
{
{"x-skypetoken", token.Value},
{"x-skype-client", "1418/8.134.0.202"},
{"Origin", "https://web.skype.com"}
};
return nvcSArgs;
};
Here, we define essential request headers for authentication and compatibility. The x-skypetoken is a crucial element, as it ensures access to Skype’s search API.
Handling API Responses & Retrying on Failure
if (jsonResponse == "")
{
token = new SkypeToken();
return Search(searchParameter, token, ++maxRecursion);
}
If an empty response is received (potentially due to an API rate limit), the method refreshes the authentication token and retries the request up to five times to prevent excessive loops.
Enhancing API Response with Profile Avatars
foreach (var node in jResponse["results"])
{
var skypeId = node["nodeProfileData"]["skypeId"] + "";
var avatarImageUrl = string.Format(
"https://avatar.skype.com/v1/avatars/{0}/public?size=l",
skypeId);
node["nodeProfileData"]["avatarImageUrl"] = avatarImageUrl;
}
After receiving the API response, the code iterates through the user results and appends an avatarImageUrl field using Skype’s avatar service.
using System;
using System.Collections.Specialized;
using System.Net;
using System.Text;
using Newtonsoft.Json.Linq;
namespace SkypeGraph
{
public class SkypeSearch
{
public static JObject Search(string searchParameter, SkypeToken token, int maxRecursion = 0)
{
if (maxRecursion == 5) throw new Exception("Preventing excessive retries");
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 |
SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12;
var requestNumber = new Random().Next(100000, 999999);
var url = string.Format("https://search.skype.com/v2.0/search?searchString={0}&requestId={1}&locale=en-GB&sessionId={2}", searchParameter, requestNumber, Guid.NewGuid());
var http = new HTTPRequest {Encoder = Encoding.UTF8};
HTTPHeaderHandler wicket = nvc =>
{
var nvcSArgs = new NameValueCollection
{
{"x-skypetoken", token.Value},
{"x-skypegraphservicesettings", ""},
{"x-skype-client","1418/8.134.0.202"},
{"x-ecs-etag", "GAx0SLim69RWpjmJ9Dpc4QBHAou0pY//fX4AZ9JVKU4="},
{"Origin", "https://web.skype.com"}
};
return nvcSArgs;
};
http.OverrideUserAgent =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
http.OverrideAccept = "application/json";
http.TimeOut = TimeSpan.FromSeconds(5);
http.HeaderHandler = wicket;
http.ContentType = "application/json";
http.Referer = "https://web.skype.com/";
var jsonResponse = http.Request(url);
if (jsonResponse == "")
{
// In case of a 429 (Too many requests), then refresh the token.
token = new SkypeToken();
return Search(searchParameter, token, ++maxRecursion);
}
var jResponse = JObject.Parse(jsonResponse);
#region sample
/*
{
"requestId":"240120",
"results":[
{
"nodeProfileData":{
"skypeId":"live:octavioaparicio_jr",
"skypeHandle":"live:octavioaparicio_jr",
"name":"octavio aparicio",
"avatarUrl":"https://api.skype.com/users/live:octavioaparicio_jr/profile/avatar",
"country":"Mexico",
"countryCode":"mx",
"contactType":"Skype4Consumer"
}
}
]
}
*/
#endregion
foreach (var node in jResponse["results"])
{
var skypeId = node["nodeProfileData"]["skypeId"] + "";
var avatarImageUrl = string.Format("https://avatar.skype.com/v1/avatars/{0}/public?size=l", skypeId);
node["nodeProfileData"]["avatarImageUrl"] = avatarImageUrl;
}
return jResponse;
}
}
}
Using an #API to Retrieve User Details from a #QQ Account ID

QQ, one of China’s largest instant messaging platforms, assigns each user a unique account ID. If you need to retrieve user details from a QQ account ID programmatically, you can use an API such as AvatarAPI. This guide will walk you through making an API request and interpreting the returned JSON response.
API Endpoint
The API request is made to the following URL:
https://avatarapi.com/v2/api.aspx
Request Format
The API expects a POST request with a JSON body containing authentication details (username and password) along with the QQ email ID of the user you want to retrieve information for.
Example Request Body
{
"username": "demo",
"password": "demo___",
"email": "16532096@qq.com"
}
Sending the Request
You can send this request using cURL, Postman, or a programming language like Python. Here’s an example using Python’s requests library:
import requests
import json
url = "https://avatarapi.com/v2/api.aspx"
headers = {"Content-Type": "application/json"}
payload = {
"username": "demo",
"password": "demo___",
"email": "16532096@qq.com"
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())
API Response
The API returns a JSON object with the user’s details. Below is a sample response:
{
"Name": "邱亮",
"Image": "https://q.qlogo.cn/g?b=qq&nk=16532096&s=640",
"Valid": true,
"City": "",
"Country": "China",
"IsDefault": true,
"Success": true,
"RawData": "",
"Source": {
"Name": "QQ"
}
}
Explanation of Response Fields
- Name: The user’s name associated with the QQ account.
- Image: A URL to the user’s QQ avatar image.
- Valid: Boolean flag indicating if the QQ account is valid.
- City: The user’s city (if available).
- Country: The user’s country.
- IsDefault: Indicates whether the profile is using the default avatar.
- Success: Boolean flag indicating whether the API request was successful.
- RawData: Any additional raw data returned from the source.
- Source: The data provider (in this case, QQ).
Use Cases
This API can be useful for:
- Enhancing user profiles by fetching their QQ avatar and details.
- Verifying the validity of QQ accounts before allowing user actions.
- Personalizing content based on user identity from QQ.
Conclusion
Using an API to retrieve QQ user details is a straightforward process. By sending a POST request with the QQ email ID, you can obtain the user’s name, avatar, and other details. Ensure that you handle user data responsibly and comply with any relevant privacy regulations.
For production use, replace the demo credentials with your own API key and ensure secure storage of authentication details.
#UFG #API for Poland – Vehicle Insurance Details

How to Use the API for Vehicle Insurance Details in Poland
If you’re working in the insurance industry, vehicle-related services, or simply need a way to verify a car’s insurance status in Poland, there’s a powerful API available to help you out. This API provides quick and reliable access to current insurance details of a vehicle, using just the license plate number.
Overview of the API Endpoint
The API is accessible at the following endpoint:
https://www.tablicarejestracyjnaapi.pl/api/bespokeapi.asmx?op=CheckInsuranceStatusPoland
This endpoint retrieves the insurance details for vehicles registered in Poland. It uses the license plate number as the key input to return the current insurance policy information in XML format.
Key Features
The API provides the following details about a vehicle:
- PolicyNumber: The unique policy number of the insurance.
- Vehicle: The make and model of the vehicle.
- Company: The insurance company providing the policy.
- Address: The company’s registered address.
- IsBlacklisted: A boolean field indicating whether the vehicle is blacklisted.
Below is an example of the XML response:
<InsurancePolicy xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://Regcheck.org.uk/">
<PolicyNumber>920040143596</PolicyNumber>
<Vehicle>RENAULT ARES 826 RZ</Vehicle>
<Company>TOWARZYSTWO UBEZPIECZEŃ I REASEKURACJI WARTA S.A.</Company>
<Address>rondo I. Daszyńskiego 1, 00-843 Warszawa</Address>
<IsBlacklisted>false</IsBlacklisted>
</InsurancePolicy>
How to Use the API
- Send a Request: To use the API, you need to send an HTTP request to the endpoint. Typically, you’ll pass the vehicle’s license plate number as a parameter in the request body or URL query string.
- Process the Response: The response will be in XML format. You can parse the XML to extract the details you need, such as the policy number, the name of the insurance provider, and the vehicle’s blacklisting status.
Example Use Case
Imagine you’re developing a mobile application for a car rental service in Poland. Verifying the insurance status of vehicles in your fleet is crucial for compliance and operational efficiency. By integrating this API, you can:
- Automate insurance checks for newly added vehicles.
- Notify users if a vehicle’s insurance policy has expired or if the vehicle is blacklisted.
- Display detailed insurance information in the app for transparency.
Integration Tips
- Error Handling: Ensure your application handles scenarios where the API returns errors (e.g., invalid license plate numbers or no records found).
- XML Parsing: Use robust XML parsers available in your development language to process the API response efficiently.
- Security: If the API requires authentication, make sure you secure your API keys and follow best practices for handling sensitive information.
Sample Code
Here’s a quick example of how you can call the API in C#:
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Xml;
class Program
{
static async Task Main(string[] args)
{
string licensePlate = "WE12345"; // Example license plate number
string apiUrl = "https://www.tablicarejestracyjnaapi.pl/api/bespokeapi.asmx?op=CheckInsuranceStatusPoland";
using HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(apiUrl + "?licensePlate=" + licensePlate);
if (response.IsSuccessStatusCode)
{
string responseContent = await response.Content.ReadAsStringAsync();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(responseContent);
string policyNumber = xmlDoc.SelectSingleNode("//PolicyNumber")?.InnerText;
string vehicle = xmlDoc.SelectSingleNode("//Vehicle")?.InnerText;
string company = xmlDoc.SelectSingleNode("//Company")?.InnerText;
string address = xmlDoc.SelectSingleNode("//Address")?.InnerText;
string isBlacklisted = xmlDoc.SelectSingleNode("//IsBlacklisted")?.InnerText;
Console.WriteLine($"Policy Number: {policyNumber}\nVehicle: {vehicle}\nCompany: {company}\nAddress: {address}\nBlacklisted: {isBlacklisted}");
}
else
{
Console.WriteLine("Failed to retrieve data from the API.");
}
}
}
Conclusion
The API for vehicle insurance details in Poland is a valuable tool for businesses and developers looking to integrate reliable insurance data into their applications. Whether you’re building tools for insurance verification, fleet management, or compliance monitoring, this API provides an efficient way to access up-to-date information with minimal effort.
Start integrating the API today and take your application’s functionality to the next level!
How to Extract #EXIF Data from an Image in .NET 8 with #MetadataExtractor

GIT REPO : https://github.com/infiniteloopltd/ExifResearch
When working with images, EXIF (Exchangeable Image File Format) data can provide valuable information such as the camera model, date and time of capture, GPS coordinates, and much more. Whether you’re building an image processing application or simply want to extract metadata for analysis, knowing how to retrieve EXIF data in a .NET environment is essential.
In this post, we’ll walk through how to extract EXIF data from an image in .NET 8 using the cross-platform MetadataExtractor library.
Why Use MetadataExtractor?
.NET’s traditional System.Drawing.Common library has limitations when it comes to cross-platform compatibility, particularly for non-Windows environments. The MetadataExtractor library, however, is a powerful and platform-independent solution for extracting metadata from various image formats, including EXIF data.
With MetadataExtractor, you can read EXIF metadata from images in a clean, efficient way, making it an ideal choice for .NET Core and .NET 8 developers working on cross-platform applications.
Step 1: Install MetadataExtractor
To begin, you need to add the MetadataExtractor NuGet package to your project. You can install it using the following command:
bashCopy codedotnet add package MetadataExtractor
This package supports EXIF, IPTC, XMP, and many other metadata formats from various image file types.
Step 2: Writing the Code to Extract EXIF Data
Now that the package is installed, let’s write some code to extract EXIF data from an image stored as a byte array.
Here is the complete function:
using System;
using System.Collections.Generic;
using System.IO;
using MetadataExtractor;
using MetadataExtractor.Formats.Exif;
public class ExifReader
{
public static Dictionary<string, string> GetExifData(byte[] imageBytes)
{
var exifData = new Dictionary<string, string>();
try
{
using var ms = new MemoryStream(imageBytes);
var directories = ImageMetadataReader.ReadMetadata(ms);
foreach (var directory in directories)
{
foreach (var tag in directory.Tags)
{
// Add tag name and description to the dictionary
exifData[tag.Name] = tag.Description;
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error reading EXIF data: {ex.Message}");
}
return exifData;
}
}
How It Works:
- Reading Image Metadata: The function uses
ImageMetadataReader.ReadMetadatato read all the metadata from the byte array containing the image. - Iterating Through Directories and Tags: EXIF data is organized in directories (for example, the main EXIF data, GPS, and thumbnail directories). We iterate through these directories and their associated tags.
- Handling Errors: We wrap the logic in a
try-catchblock to ensure any potential errors (e.g., unsupported formats) are handled gracefully.
Step 3: Usage Example
To use this function, you can pass an image byte array to it. Here’s an example:
using System;
using System.IO;
class Program
{
static void Main()
{
// Replace with your byte array containing an image
byte[] imageBytes = File.ReadAllBytes("example.jpg");
var exifData = ExifReader.GetExifData(imageBytes);
foreach (var kvp in exifData)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}
}
}
This code reads an image from the file system as a byte array and then uses the ExifReader.GetExifData method to extract the EXIF data. Finally, it prints out the EXIF tags and their descriptions.
Example Output:
If the image contains EXIF metadata, the output might look something like this:
"Compression Type": "Baseline",
"Data Precision": "8 bits",
"Image Height": "384 pixels",
"Image Width": "512 pixels",
"Number of Components": "3",
"Component 1": "Y component: Quantization table 0, Sampling factors 2 horiz/2 vert",
"Component 2": "Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert",
"Component 3": "Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert",
"Make": "samsung",
"Model": "SM-G998B",
"Orientation": "Right side, top (Rotate 90 CW)",
"X Resolution": "72 dots per inch",
"Y Resolution": "72 dots per inch",
"Resolution Unit": "Inch",
"Software": "G998BXXU7EWCH",
"Date/Time": "2023:05:02 12:33:47",
"YCbCr Positioning": "Center of pixel array",
"Exposure Time": "1/33 sec",
"F-Number": "f/2.2",
"Exposure Program": "Program normal",
"ISO Speed Ratings": "640",
"Exif Version": "2.20",
"Date/Time Original": "2023:05:02 12:33:47",
"Date/Time Digitized": "2023:05:02 12:33:47",
"Time Zone": "+09:00",
"Time Zone Original": "+09:00",
"Shutter Speed Value": "1 sec",
"Aperture Value": "f/2.2",
"Exposure Bias Value": "0 EV",
"Max Aperture Value": "f/2.2",
"Metering Mode": "Center weighted average",
"Flash": "Flash did not fire",
"Focal Length": "2.2 mm",
"Sub-Sec Time": "404",
"Sub-Sec Time Original": "404",
"Sub-Sec Time Digitized": "404",
"Color Space": "sRGB",
"Exif Image Width": "4000 pixels",
"Exif Image Height": "3000 pixels",
"Exposure Mode": "Auto exposure",
"White Balance Mode": "Auto white balance",
"Digital Zoom Ratio": "1",
"Focal Length 35": "13 mm",
"Scene Capture Type": "Standard",
"Unique Image ID": "F12XSNF00NM",
"Compression": "JPEG (old-style)",
"Thumbnail Offset": "824 bytes",
"Thumbnail Length": "49594 bytes",
"Number of Tables": "4 Huffman tables",
"Detected File Type Name": "JPEG",
"Detected File Type Long Name": "Joint Photographic Experts Group",
"Detected MIME Type": "image/jpeg",
"Expected File Name Extension": "jpg"
This is just a small sample of the information EXIF can store. Depending on the camera and settings, you may find data on GPS location, white balance, focal length, and more.
Why Use EXIF Data?
EXIF data can be valuable in various scenarios:
- Image processing: Automatically adjust images based on camera settings (e.g., ISO or exposure time).
- Data analysis: Track when and where photos were taken, especially when handling large datasets of images.
- Digital forensics: Verify image authenticity by analyzing EXIF metadata for manipulation or alterations.
Conclusion
With the MetadataExtractor library, extracting EXIF data from an image is straightforward and cross-platform compatible. Whether you’re building a photo management app, an image processing tool, or just need to analyze metadata, this approach is an efficient solution for working with EXIF data in .NET 8.
By using this solution, you can extract a wide range of metadata from images, making your applications smarter and more capable. Give it a try and unlock the hidden data in your images!