A-melding Submissions

A-melding (arbeidsgiver-melding) is the mandatory Norwegian employment and income report that employers must submit to Skatteetaten (the Norwegian Tax Administration) for each payroll period. The API allows you to preview, submit, and track a-melding submissions.

Submissions are created from posted payroll runs and sent to Skatteetaten via the Altinn/Maskinporten integration.

Endpoints

List Submissions

GET /api/v2/payroll/amelding-submissions

Retrieves a paginated list of a-melding submissions.

Query Parameters

Parameter Type Required Description
client_account_id integer Yes Filter by client account
period_year integer No Filter by year
period_month integer No Filter by month (1–12)
status string No Filter by status: DRAFT, SUBMITTED, ACCEPTED, REJECTED, or SEND_FAILED
page integer No Page number (default: 1)
per_page integer No Items per page (default: 100)

Submissions are returned newest period first — period_year, period_month and id are all sorted descending — so the current period’s newest attempt is the first row and a replaced attempt follows it. The last row is the oldest.

Response

{
  "data": [
    {
      "id": 1,
      "created_by_id": 7,
      "created_at": "2024-06-01T10:00:00Z",
      "client_account_id": 7,
      "period_year": 2024,
      "period_month": 6,
      "meldings_id": "m-1234567890",
      "erstatter_meldings_id": null,
      "status": "ACCEPTED",
      "idempotency_key": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "payload": { },
      "response": { },
      "feedback": { },
      "error_details": null,
      "submitted_at": "2024-06-01T10:05:00Z",
      "submitted_by_id": 7,
      "dialog_id": null,
      "transmission_id": null,
      "dialogporten_dialog_id": null
    }
  ],
  "meta": {
    "page": 1,
    "pages": 1,
    "per_page": 100,
    "records": 1
  }
}

Get Submission

GET /api/v2/payroll/amelding-submissions/{id}

Retrieves a specific a-melding submission by ID.

Response

Returns a single submission object (same shape as the list response items).


Preview Submission

POST /api/v2/payroll/amelding-submissions/preview

Generates a preview of the a-melding payload that would be sent to Skatteetaten, without actually submitting it. Use this to review the data before submitting.

Request Body

Field Type Required Description
client_account_id integer Yes The client account ID
period_year integer Yes The reporting year (2020–2100)
period_month integer Yes The reporting month (1–12)

Example Request

{
  "client_account_id": 7,
  "period_year": 2024,
  "period_month": 6
}

Response

{
  "payload": { },
  "warnings": [
    {
      "contract_id": 42,
      "business_partner_id": 56,
      "employee_name": "Ola Nordmann",
      "missing_fields": ["work_percentage", "last_salary_change_date"],
      "invalid_fields": []
    }
  ]
}

The payload object contains the full a-melding JSON structure that would be sent to Skatteetaten, including employee income details, tax deductions, and employer information.

warnings lists the ordinary employment contracts in the period that Skatteetaten will flag with an immediate deviation (MAGNET_EDAG-291) even though it accepts the submission. Each entry covers one contract:

Field Type Description
contract_id integer The employment contract the warning is about
business_partner_id integer The employee
employee_name string The employee’s name, or #<business_partner_id> when the partner has no name
missing_fields array Contract fields required for an ordinary arbeidsforhold that are empty: occupation_code_lv, work_percentage, weekly_hours, work_time_arrangement_lv, employment_form, last_salary_change_date
invalid_fields array Contains occupation_code_lv when the occupation code is not in SSB’s current catalogue

warnings is an empty array when nothing needs attention. Only contracts with employment_type EMPLOYED and an employee with a personal number are checked — employees without one are left out of the payload, so they raise no warning.


Submit A-melding

POST /api/v2/payroll/amelding-submissions

Prepares and submits an a-melding to Skatteetaten for a given payroll period. The submission is created, then immediately sent to Skatteetaten via the Altinn integration.

Request Body

Field Type Required Description
client_account_id integer Yes The client account ID
period_year integer Yes The reporting year (2020–2100)
period_month integer Yes The reporting month (1–12)

Example Request

{
  "client_account_id": 7,
  "period_year": 2024,
  "period_month": 6
}

Response

Returns the created submission object with status SUBMITTED on success. A submission that never reached Skatteetaten (authentication, network, or API error) is still returned with 200 OK, but with status SEND_FAILED and the reason in error_details — check status rather than the HTTP code.

{
  "id": 1,
  "created_by_id": 7,
  "created_at": "2024-06-01T10:00:00Z",
  "client_account_id": 7,
  "period_year": 2024,
  "period_month": 6,
  "meldings_id": "m-1234567890",
  "erstatter_meldings_id": null,
  "status": "SUBMITTED",
  "idempotency_key": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "payload": { },
  "response": { },
  "feedback": null,
  "error_details": null,
  "submitted_at": "2024-06-01T10:05:00Z",
  "submitted_by_id": 7,
  "dialog_id": "d-abcdef123456",
  "transmission_id": "t-abcdef123456",
  "dialogporten_dialog_id": null
}

Submission Flow

  1. The system prepares the a-melding payload from posted payroll runs for the specified period
  2. The payload is sent to Skatteetaten via the Altinn/Maskinporten integration
  3. On success, the status is set to SUBMITTED and background tasks are queued to sync feedback from Skatteetaten
  4. If the send fails, the status is set to SEND_FAILED and error_details records the upstream status code, message, and response body
  5. If Skatteetaten already received a submission for the same period, the new submission replaces it: erstatter_meldings_id references the latest SUBMITTED or ACCEPTED attempt, skipping newer failed or rejected ones

Attributes

Attribute Type Description
id integer Unique identifier (read-only)
created_by_id integer ID of the creating user (read-only)
created_at datetime Creation timestamp (read-only)
client_account_id integer ID of the client account (read-only)
period_year integer Reporting year (read-only)
period_month integer Reporting month, 1–12 (read-only)
meldings_id string Skatteetaten-assigned submission ID (read-only)
erstatter_meldings_id string ID of the previous submission this one replaces, if any (read-only)
status string Current status: DRAFT, SUBMITTED, ACCEPTED, REJECTED, or SEND_FAILED (read-only)
idempotency_key string UUID used for idempotent submission (read-only)
payload object The a-melding payload sent to Skatteetaten (read-only)
response object The response from Skatteetaten (read-only)
feedback object Feedback received from Skatteetaten after processing (read-only)
error_details object Details about the submission’s outcome (read-only). Set on failures, but also on an ACCEPTED submission that Skatteetaten flagged with non-blocking deviations — branch on status, never on error_details being non-null. Four shapes: a failed send carries status_code, message, and a truncated response_body; an a-melding that could not be built carries only message; A03 feedback carries mottakstatus (avvist, mottatt, or erstattet) and the avvik deviation list, on REJECTED and ACCEPTED rows; a finding from an uploaded A07 reconciliation report carries source, status, altinn_reference, and reconciled_at
submitted_at datetime When the submission was sent (read-only)
submitted_by_id integer ID of the user who submitted (read-only)
dialog_id string Dialogporten dialog ID for tracking (read-only)
transmission_id string Transmission ID from Altinn (read-only)
dialogporten_dialog_id integer Internal Dialogporten dialog reference (read-only)

Submission Statuses

Value Description
DRAFT Submission prepared but not yet sent to Skatteetaten
SUBMITTED Sent to Skatteetaten, awaiting processing and feedback
ACCEPTED Accepted by Skatteetaten. error_details may still be set, carrying the non-blocking avvik deviations Skatteetaten reported
REJECTED Received by Skatteetaten and refused (A03 “avvist”)
SEND_FAILED Never reached Skatteetaten — an authentication, network, or API error, or an a-melding that could not be built. Retryable. Only the scheduled submission task records the build-failure case; an interactive POST answers 400 instead (see Error Responses)

Error Responses

Status Code Description
400 Invalid request (missing required fields, invalid year/month range)
400 payroll.amelding_invalid_contract_value — an employment contract holds a value the a-melding cannot report (an unmapped enum, or an arbeidstidsordning Skatteetaten does not know). POST and POST .../preview answer this instead of returning a submission
403 Forbidden (no access to client account). The list endpoint requires client_account_id — omitting it answers 403 for ordinary API callers
404 Submission not found

Business Rules

  1. A-meldinger are built from posted payroll runs — you must have completed payroll runs for the period before submitting
  2. period_year must be between 2020 and 2100, and period_month must be between 1 and 12
  3. Submitting a new a-melding for a period Skatteetaten has already received creates a replacement (korrigert a-melding). Failed and rejected attempts are skipped when picking what to replace, so a retry after a SEND_FAILED does not replace anything
  4. After successful submission, background tasks automatically sync feedback from Skatteetaten
  5. A REJECTED finding never overrides an ACCEPTED submission — a late rejection for an a-melding that has since been accepted is logged and the status left alone
  6. All fields on the submission are read-only — the system builds the payload automatically from payroll data