API Reference

REST API Reference

Base URL: https://api.embeddx.org/v2. Bearer token required.

Authentication

Put a Bearer token in Authorization for every request. Create API keys in account settings.

Authorization: Bearer embx_sk_your_api_key

Keys follow your account plan. Limits by plan: Explorer 3 req/day, Engineer 100 req/day, Team 500 req/day, Enterprise custom.

POST /upload

POST /upload accepts a PDF, extracts its register model, and returns a stable Chip ID for generation.

Request

POST /v2/upload
Content-Type: multipart/form-data

file: (binary PDF)
chip_name: "STM32L476RG"          // optional hint

Response 200

{
  "chip_id": "embx_chip_stm32l476rg_a1b2c3",
  "chip_name": "STM32L476RG",
  "peripherals": ["GPIO", "USART", "SPI", "I2C", "TIM", "ADC"],
  "register_count": 847,
  "datasheet_pages": 1648
}

POST /generate

Generate driver output. Small datasheets under 400 pages return synchronously; larger ones return a job ID for polling.

Request body

{
  "chip_id": "embx_chip_stm32l476rg_a1b2c3",
  "lang": "c99",                        // "c99" | "cpp17" | "rust"
  "peripherals": ["GPIO", "USART"],    // omit for all
  "include_test_stubs": false,           // Engineer+ only
  "webhook_url": "https://..."            // optional
}

Response 200 (sync, small datasheet)

{
  "status": "complete",
  "chip_id": "embx_chip_stm32l476rg_a1b2c3",
  "files": [
    {
      "filename": "stm32l476rg_gpio.h",
      "content_base64": "..."
    },
    {
      "filename": "stm32l476rg_usart.h",
      "content_base64": "..."
    }
  ],
  "smoke_test": "pass",
  "register_count": 191,
  "accessor_count": 1342
}

Response 202 (async, large datasheet)

{
  "status": "queued",
  "job_id": "embx_job_x9y8z7w6",
  "estimated_seconds": 45
}

GET /jobs/{id}

Check an async generation job's status.

$ curl https://api.embeddx.org/v2/jobs/embx_job_x9y8z7w6 \
    -H "Authorization: Bearer embx_sk_..."

Response (complete)

{
  "job_id": "embx_job_x9y8z7w6",
  "status": "complete",
  "files": [/* same as sync response */],
  "smoke_test": "pass"
}

Possible status values

StatusMeaning
queuedAccepted, awaiting a worker
processingExtraction and generation in progress
completeOutput is in files
failedGeneration failed, see error_code

GET /chips

List library chips and IDs. A library ID skips upload for validated chips.

{
  "chips": [
    {
      "chip_id": "embx_lib_stm32l476rg",
      "chip_name": "STM32L476RG",
      "vendor": "STMicroelectronics",
      "peripherals": ["GPIO", "USART", "SPI", "I2C", "TIM", "ADC", "DMA"]
    }
    /* ... */
  ],
  "total": 183
}

Webhook callbacks

Add webhook_url to the generation request to POST a completion callback. Its payload matches GET /jobs/{id}.

The X-Embedd-Signature header carries an HMAC-SHA256 signature of the raw body, made with your account's webhook secret. Verify it before processing.

Signature verification (Python)

import hmac, hashlib

def verify_webhook(secret, payload_bytes, signature_header):
    expected = hmac.new(
        secret.encode(),
        payload_bytes,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature_header)

On HTTP 4xx/5xx, deliveries retry with exponential backoff up to 3 times. Return HTTP 200 to acknowledge.

Error codes

HTTPCodeMeaning
401INVALID_KEYAPI key missing or invalid
403PLAN_LIMITRequest exceeds plan quota
404CHIP_NOT_FOUNDChip ID does not exist
413FILE_TOO_LARGEPDF exceeds 200 MB limit
422EXTRACTION_FAILEDRegister model extraction from the PDF failed
422UNSUPPORTED_LANGLanguage unavailable on plan
429RATE_LIMITEDToo many requests. Retry using Retry-After.
500INTERNAL_ERRORServer error; the request ID is in X-Request-ID.

Every error response has a JSON body containing error_code and message.