REST API Free Tier Multi-metadata detection

metadata detection API

Extract Metadata from images programmatically with a single API call. Built for developers who need accurate labels, confidence scores, and optional metadata fieldes at scale.

Why Use This API

AI metadata detection

Advanced AI models trained on broad visual datasets. Accurately identifies common metadata categories from real-world scenes.

Confidence Scoring

Returns confidence values for each detection so you can filter low-certainty predictions in production pipelines.

metadata field Output

Optionally includes metadata field coordinates so you can draw overlays or crop detected metadata.

Multi-metadata detection

Detect and identify multiple different metadata within a single image. Perfect for analyzing complex designs.

Quick Start

Start identifying metadata in under a minute. Here's how:

  1. Get your API keySign up free to receive your key
  2. Send a request — POST an image containing one or more metadata to the endpoint
  3. Get the result — Receive identified metadata as JSON with confidence scores
curl -X POST https://precisioncounter.com/api/v1/extract-image-metadata \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "image=@sample.png"
import requests

response = requests.post(
    "https://precisioncounter.com/api/v1/extract-image-metadata",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    files={"image": open("sample.png", "rb")}
)

data = response.json()
for metadata in data["metadata"]:
    print(f"{metadata['name']} ({metadata['confidence']:.0%})")
const fs = require("fs");
const FormData = require("form-data");

const form = new FormData();
form.append("image", fs.createReadStream("sample.png"));

const response = await fetch(
  "https://precisioncounter.com/api/v1/extract-image-metadata",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      ...form.getHeaders()
    },
    body: form
  }
);

const data = await response.json();
data.metadata.forEach(f => console.log(`${f.name} (${f.confidence})`));

API Reference

Base URL

https://precisioncounter.com/api/v1

Authentication

All requests require an API key passed in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Extract Metadata

POST /api/v1/extract-image-metadata

Detects metadata from an uploaded image and returns structured detection results as JSON.

Request Parameters

Parameter Type Description
image required file Image file to analyze for metadata detection. Accepted formats: PNG, JPG, JPEG, WebP. Max size: 10 MB.
max_fields optional integer Max number of metadata detections to return. Default: 5. Range: 1-20.
include_exif optional boolean Include metadata field coordinates for each detection. Default: true.

Response

200 OK — Returns identified metadata data as JSON.

{
  "metadata": [
    {
      "name": "person",
      "confidence": 0.94,
      "category": "person",
      "box": {
        "x": 124,
        "y": 52,
        "width": 300,
        "height": 540
      }
    }
  ],
  "image_width": 1280,
  "image_height": 720,
  "processing_time_ms": 450
}

Response Headers

Header Value
Content-Type application/json
X-Credits-Remaining Number of API credits remaining
X-Processing-Time Processing time in milliseconds

Code Examples

Full Examples (with error handling)

curl -X POST https://precisioncounter.com/api/v1/extract-image-metadata \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "image=@sample.png" \
  -F "max_fields=5" \
  -F "include_exif=true"
import requests
import sys

API_KEY = "YOUR_API_KEY"
API_URL = "https://precisioncounter.com/api/v1/extract-image-metadata"

def detect_metadata(input_path, max_fields=5):
    """Extract Metadata from an image file."""
    with open(input_path, "rb") as img:
        response = requests.post(
            API_URL,
            headers={"Authorization": f"Bearer {API_KEY}"},
            files={"image": img},
            data={"max_fields": max_fields, "include_exif": "true"}
        )

    if response.status_code == 200:
        data = response.json()
        for metadata in data["metadata"]:
            print(f"{metadata['name']} - {metadata['confidence']:.0%} confidence")
            print(f"  Category: {metadata['category']}")
            if metadata.get("box"):
              print(f"  Box: {metadata['box']}")
        print(f"Credits remaining: {response.headers.get('X-Credits-Remaining')}")
    else:
        print(f"Error {response.status_code}: {response.json()['error']}")

detect_metadata("sample.png")
const fs = require("fs");
const FormData = require("form-data");
const fetch = require("node-fetch");

const API_KEY = "YOUR_API_KEY";
const API_URL = "https://precisioncounter.com/api/v1/extract-image-metadata";

async function detectmetadata(inputPath, maxResults = 5) {
  const form = new FormData();
  form.append("image", fs.createReadStream(inputPath));
  form.append("max_fields", String(maxResults));
  form.append("include_exif", "true");

  const response = await fetch(API_URL, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${API_KEY}`,
      ...form.getHeaders()
    },
    body: form
  });

  if (response.ok) {
    const data = await response.json();
    data.metadata.forEach(metadata => {
      console.log(`${metadata.name} - ${(metadata.confidence * 100).toFixed(0)}%`);
      console.log(`  Category: ${metadata.category}`);
      if (metadata.box) console.log(`  Box: ${JSON.stringify(metadata.box)}`);
    });
    console.log(`Credits: ${response.headers.get("x-credits-remaining")}`);
  } else {
    const error = await response.json();
    console.error(`Error ${response.status}: ${error.error}`);
  }
}

detectmetadata("sample.png");
<?php
$api_key = "YOUR_API_KEY";
$url = "https://precisioncounter.com/api/v1/extract-image-metadata";

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $api_key"
    ],
    CURLOPT_POSTFIELDS => [
        "image" => new CURLFile("sample.png"),
        "max_fields" => "5",
        "include_exif" => "true"
    ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode === 200) {
    $data = json_decode($response, true);
    foreach ($data["metadata"] as $metadata) {
        echo $metadata["name"] . " - " . ($metadata["confidence"] * 100) . "% confidence\n";
        echo "  Category: " . $metadata["category"] . "\n";
        if (isset($metadata["box"])) {
          echo "  Box: " . json_encode($metadata["box"]) . "\n";
        }
    }
} else {
    echo "Error $httpCode: $response\n";
}
?>
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "mime/multipart"
    "net/http"
    "os"
)

type metadataResult struct {
    Name       string   `json:"name"`
    Confidence float64  `json:"confidence"`
    Category   string   `json:"category"`
  Box        map[string]int `json:"box"`
}

type Response struct {
  metadata        []metadataResult `json:"metadata"`
  ImageWidth     int            `json:"image_width"`
  ImageHeight    int            `json:"image_height"`
  ProcessingTime int            `json:"processing_time_ms"`
}

func detectmetadata(inputPath string) error {
    file, _ := os.Open(inputPath)
    defer file.Close()

    body := &bytes.Buffer{}
    writer := multipart.NewWriter(body)
    part, _ := writer.CreateFormFile("image", inputPath)
    io.Copy(part, file)
    writer.WriteField("max_fields", "5")
    writer.Close()

    req, _ := http.NewRequest("POST",
        "https://precisioncounter.com/api/v1/extract-image-metadata", body)
    req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
    req.Header.Set("Content-Type", writer.FormDataContentType())

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    if resp.StatusCode == 200 {
        var result Response
        json.NewDecoder(resp.Body).Decode(&result)
        for _, metadata := range result.metadata {
            fmt.Printf("%s - %.0f%% confidence\n", metadata.Name, metadata.Confidence*100)
        }
    }
    return nil
}

func main() {
    detectmetadata("sample.png")
}
require "net/http"
require "uri"
require "json"

api_key = "YOUR_API_KEY"
uri = URI("https://precisioncounter.com/api/v1/extract-image-metadata")

form_data = [
  ["image", File.open("sample.png", "rb")],
  ["max_fields", "5"],
  ["include_exif", "true"]
]

req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{api_key}"
req.set_form(form_data, "multipart/form-data")

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

if res.code == "200"
  data = JSON.parse(res.body)
  data["metadata"].each do |metadata|
    puts "#{metadata['name']} - #{(metadata['confidence'] * 100).round}% confidence"
    puts "  Category: #{metadata['category']}"
    puts "  Box: #{metadata['box']}" if metadata['box']
  end
else
  puts "Error #{res.code}: #{res.body}"
end
using System.Text.Json;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_API_KEY");

using var form = new MultipartFormDataContent();
var imageContent = new ByteArrayContent(File.ReadAllBytes("sample.png"));
imageContent.Headers.ContentType = new("image/png");
form.Add(imageContent, "image", "sample.png");
form.Add(new StringContent("5"), "max_fields");
form.Add(new StringContent("true"), "include_exif");

var response = await client.PostAsync(
    "https://precisioncounter.com/api/v1/extract-image-metadata", form);

if (response.IsSuccessStatusCode)
{
    var json = await response.Content.ReadAsStringAsync();
    var data = JsonSerializer.Deserialize<JsonElement>(json);
    foreach (var metadata in data.GetProperty("metadata").EnumerateArray())
    {
        Console.WriteLine($"{metadata.GetProperty("name")} - {metadata.GetProperty("confidence")}");
    }
}

Error Handling

The API returns standard HTTP status codes with JSON error bodies:

Status Meaning Description
200 Success metadata identified successfully. Response body contains JSON with metadata data.
400 Bad Request Missing image file, unsupported format, or file too large.
401 Unauthorized Missing or invalid API key.
429 Rate Limited Too many requests. Wait and retry with exponential backoff.
500 Server Error Internal processing error. Retry the request.

Error Response Format

{
  "error": "Invalid file format. Accepted: png, jpg, jpeg, webp",
  "code": "INVALID_FORMAT",
  "status": 400
}

Rate Limits

Plan Requests / Minute Max File Size Max Resolution
Free 10 10 MB 4096 x 4096 px
Pro 60 25 MB 8192 x 8192 px

Rate limit headers are included in every response:

X-RateLimit-Limit: 10
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 1708646400

Use Cases

  • Design asset management
  • Brand consistency checking
  • Web scraping metadata detection
  • Accessibility compliance
  • Print production
  • image analysis research
  • Design tool plugins
  • detection workflow verification

Pricing

Free to Start

Get free API credits when you sign up. No credit card required.

Frequently Asked Questions

What image formats does the Image Metadata Extractor API support?
The API accepts PNG, JPG, JPEG, and WebP images. Upload any image containing one or more metadata, and the API will return structured detections.
Is the Image Metadata Extractor API free?
Yes. You get free API calls to try the service when you sign up. No credit card is required to get started.
How accurate is the metadata identification?
The API uses modern vision models trained across many categories. Accuracy depends on image quality, lighting, and occlusion, and is strongest on clear images with distinct subjects.
Can the API detect multiple metadata in one image?
Yes. The API can detect and identify multiple different metadata within a single image. Use the max_fields parameter to control how many metadata detections are returned, up to 20 per request.
Does the API return metadata fieldes?
Yes. By default, the API includes metadata field coordinates for each detected metadata. You can disable this with the include_exif parameter set to false.
What information does the API return for each metadata?
For each detected metadata, the API returns a label, confidence score (0-1), category, and optional metadata field coordinates, plus processing metadata.
Does the API store my images?
No. Images are processed in memory and immediately discarded after the response is sent. We do not store, log, or share any uploaded images.