Errors
The HTTP status tells you how a call went. When it went wrong, the body is Problem Details (RFC 9457), with the same fields on every endpoint.
Status codes
| Status | Means | What to do |
|---|---|---|
200, 201 | It went well. 201 means something new was created. | - |
400 | The request is not valid: a missing or wrong field, or JSON that cannot be read. | Fix the request. errors names the fields. |
401 | No token, or one that is unknown, expired or switched off. | Get a new token and try once more. See Sign-in. |
403 | The token lacks the scope the endpoint needs. | Ask for a token with the scope, or ask Frantz for it. |
404 | Nothing with this id belongs to you. Something that does not exist and something that belongs to another partner answer the same. | Check the id. |
405 | The address exists, but not for this method. The Allow header lists the methods it takes. A POST to http is redirected to https, arrives as GET and gets this answer. | Use the method in the reference, and always https. |
409 | The campaign's status does not allow the change, such as changing a campaign that is ordered or cancelling one that is set up, or Frantz is working on it. Also a new campaign with an externalReference you have used, or a call whose Idempotency-Key is still in use by the first call with it. | Get the campaign to see its status. For the key, wait and send the call again. |
412 | The draft changed after you read it, so the If-Match you sent is not its ETag any more. | Get the draft again and repeat the change. |
415 | The body is not sent as JSON. | Send Content-Type: application/json. |
422 | A rule stops the request, such as a budget outside the limits. | See Rules. |
429 | Too many calls: more than 3 000 a minute from one partner, or more than 30 sign-ins a minute from one address. | Wait the seconds in the Retry-After header, then go on. |
5xx | Something failed at Frantz. | Try again later. See What to retry. |
The token endpoint is the one exception: it answers errors the OAuth way. See When sign-in fails.
Problem Details
An error has the content type application/problem+json and a body like this:
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "Not Found",
"status": 404,
"traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00"
}| Field | What it is |
|---|---|
status | The HTTP status again. |
type | Names the kind of error. Base decisions in your code on the status and type. |
title, detail | For people. The wording can change, so do not parse it. |
errors | Only on invalid requests. See below. |
traceId | Identifies the call at Frantz. Log it. |
Invalid requests
A 400 for an invalid request has errors, with the field names as you send them and what is
wrong with each:
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": {
"landingPageUrl": ["Must be an https address."],
"endDate": ["Must not be before startDate."]
},
"traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00"
}Rules
A 422 means Frantz understood the request, but a rule stops it. type names the rule and
points to it here, detail says what is wrong, and errors names the field it is about.
| Rule | Field | Means |
|---|---|---|
budget-outside-limits | budget | The budget for the media products is below the minimum or above the maximum for them. Ask for a quote without budget to see budget.min and budget.max. |
application-due-date-in-the-past | applicationDueDate | The application due date has passed. |
no-media-products | mediaProductIds, or audienceId or styrk when you leave mediaProductIds out | The quote has no media products: you sent an empty mediaProductIds, or you left it out and Frantz proposes none for the audience. |
media-product-not-available | mediaProductIds | A media product you chose is neither proposed for the audience nor one you can choose. See GET /api/v2/media-products. |
advertiser-not-available | advertiserId, organizationNumber | You cannot order for the advertiser, or none of the advertisers you can order for has the organization number. See GET /api/v2/advertisers. |
organization-number-mismatch | organizationNumber | You sent both advertiserId and organizationNumber, and the number is not that advertiser's. |
organization-number-ambiguous | organizationNumber | Several of the advertisers you can order for have the organization number. Send advertiserId instead. |
audience-not-available | audienceId, styrk | No active audience has the id, and no active one has the STYRK code. An audience id that is not active falls back to styrk when you send it. See GET /api/v2/audiences. |
geography-not-available | geographyId | No active place has the id. See GET /api/v2/geographies, which lists only active places. |
quote-not-available | quoteId | You have no quote with the id. A quote is yours when you asked for it with POST /api/v2/campaign-quotes. |
quote-expired | quoteId, or none when you order | The quote's validUntil has passed. Ask for a new quote and set its quoteId on the campaign. A quote Frantz made from your choices never expires this way: it is made again at today's prices when you order. |
job-advert-not-available | connectId | You have no active job advert with the ConnectID. See POST /api/v2/job-adverts. |
job-advert-has-campaign | connectId | Another campaign is measured under the job advert. A job advert can have one campaign. |
orderer-not-available | orderedByEmail, or none when you leave it out | No active user at your company in Frantz Business Manager has the email, or your company has no active user at all to order the campaign. |
too-many-files | none | The campaign has 25 files, which is the most it can have. A refused file does not count. |
creative-awaiting-upload | none | A file you added is not uploaded yet. Upload it to its uploadUrl and order again. A file not uploaded before uploadExpires is refused, and then does not stop the order. |
idempotency-key-reused | Idempotency-Key | You sent the key before with another call: another address or another body. Use a new key for a new call. |
no-invoice-receiver | none | Your company has no invoice receiver in Frantz, so the campaign cannot be invoiced. Ask Frantz to add one, and order again. |
order-limit-reached | none | The order would take you past how many campaigns you can order through the API in a day, or how much they can cost together. Frantz sets both limits for you; detail says which one. A day is a calendar day in Norway, and a campaign you cancelled does not count. Order again tomorrow, or ask Frantz to raise the limit. |
What to retry
- Network errors, timeouts,
500,502,503and504: try again after a pause that grows, such as 1, 2 and 4 seconds, and give up after a few tries. 401: get a new token and try once more.429: wait the seconds inRetry-After, then send the call again.- Other
4xx: do not repeat the same request. It will fail the same way.
Sending a job advert is safe to repeat: POST /api/v2/job-adverts with the same
externalReference updates the job advert you have, and never makes a second one. Creating a campaign with
an externalReference you have used answers 409 and makes nothing, so find the campaign with
GET /api/v2/campaigns?externalReference=. Ordering a campaign that is ordered, or cancelling one that is
cancelled, changes nothing. Creating a
draft and adding material take an Idempotency-Key: the same call with the same key gets the first answer
again. See Repeating a call safely.
Asking Frantz about an error
Send Frantz the traceId, the time of the call, the method and address, and the status. Never send a
client secret or a token.