CTO
10.3.2026
Málstaður's product functionality is now accessible via API at https://api.malstadur.is. There you can access proofreading, speech recognition and translations, as well as additional functionality such as plain language and summarisation at a later date.
Til að fá aðgang að forritaskilum þarf fyrst að stofna til frjálsrar áskriftar. Þá geta eigendur og stjórnendur áskriftar nálgast síðu um forritaskil í notendavalmyndinni niðri til vinstri:
To get access to the API, you first need to create a frjáls áskrift subscription. This enables subscription owners and administrators to access the forritaskil API management page in the user menu in the bottom left:
There you can create API keys with specified permissions and validity periods, as well as monitor usage and costs. The services that the keys can be used for are:
Proofreading (/v1/grammar): The same proofreading that is available in Málfríður.
Speech recognition (/v1/asr): The same speech recognition that is available in Hreimur.
Translations (/v1/translate): The same translation functionality that is available in Erlendur.
Text transformation: At the moment, no endpoints for text transformation are active, but endpoints for summarisation and plain language, among others, will be added here.
General access to the API costs nothing beyond the general fee for a subscription, but usage is subject to the following charges:
1 kr. / 100 characters for proofreading, translations and text transformation.
2.000 kr. / hour for speech recognition.
Usage credit included with a subscription can only be used on the website and not on the API.
If you need greater access to the API, e.g. for formal operation of a product with fewer restrictions on the number of requests at any given time (rate limit), this can be provided with a specific service agreement.
Below are simple examples of how to use the main APIs in Python, all of which follow the setup below (assuming that httpx is installed in the environment):
import httpx
API_KEY = "YOUR_API_KEY"
BASE = "https://api.malstadur.is/v1"
HEADERS = {"X-API-KEY": API_KEY, "Content-Type": "application/json"}You can submit multiple texts at once, e.g. different paragraphs, and receive a corrected version of each one, along with markings of the changes made:
texts = [
"Ég fór í búðina og keypti mér eina mjólk.",
"Hún sagðist vera komin heim alla dagana."
]
resp = httpx.post(f"{BASE}/grammar", headers=HEADERS, json={"texts": texts})
resp.raise_for_status()
data = resp.json()
for i, result in enumerate(data["results"]):
print(f"Original text: {result['originalText']}")
print(f"Corrected text: {result['changedText']}")
if result["diffAnnotations"]:
for ann in result["diffAnnotations"]:
print(f"[{ann['changeType']}] \"{ann['origString']}\" -> \"{ann['changedString']}\"")
else:
print("No corrections")from pathlib import Path
import time
# 1. Get path and content type of media file
path = Path("YOUR_MEDIA_FILE_PATH")
ext_to_mime = {
".mp3": "audio/mpeg",
".wav": "audio/wav",
".m4a": "audio/mp4",
".ogg": "audio/ogg",
".flac": "audio/flac",
".mp4": "video/mp4",
".webm": "video/webm",
}
content_type = ext_to_mime.get(path.suffix.lower(), "audio/mpeg")
file_size = path.stat().st_size
# 2. Get presigned upload URL
presign = httpx.post(
f"{BASE}/uploads/presign",
headers=HEADERS,
json={"content_type": content_type, "file_size": file_size}
)
presign.raise_for_status()
presign_data = presign.json()
# 3: Upload file directly to storage
upload = httpx.put(
presign_data["uploadUrl"],
data=path.read_bytes(),
headers={
"Content-Type": content_type,
"Content-Length": str(file_size),
"x-amz-acl": "public-read",
},
)
upload.raise_for_status()
# 4: Create transcription task
task = httpx.post(
f"{BASE}/asr/tasks",
headers=HEADERS,
json={"url": presign_data["objectUrl"], "input_language": "is"},
)
task.raise_for_status()
task_data = task.json()
task_id = task_data["taskId"]
# 5: Poll until completion
while True:
status_resp = httpx.get(f"{BASE}/asr/tasks/{task_id}", headers=HEADERS)
status_resp.raise_for_status()
status = status_resp.json()
if status["status"] == "completed":
for seg in status["result"]:
print(f" {seg['start']:6.1f}s - {seg['end']:6.1f}s : {seg['text']}")
break
elif status["status"] == "failed":
print(f"\nError: task failed: {status.get('error', 'unknown')}")
break
else:
print(f"Task status: {status['status']} (progress: {status['progress']*100:.1f}%)")
time.sleep(5) # Wait 5 seconds before polling againFor translations, two types of endpoints can be used. Firstly, /translate, which is intended for smaller text snippets where the client simply waits for a response (see example below), and secondly, /translate/tasks/{id}, which works similarly to speech recognition, where one or more tasks are initiated and the result is then retrieved in a separate call. Both endpoints also support receiving a glossary, but it is also possible to retrieve glossaries that belong to a group on Málstaður.
text = "The weather in Reykjavik is beautiful today, although a bit cold."
resp = httpx.post(f"{BASE}/translate", headers=HEADERS, json={"text": text, "targetLanguage": "is"})
resp.raise_for_status()
data = resp.json()
print(f"Translation: {data['text']}")Á næstunni munum við svo bæta við forritaskilum fyrir m.a. samantekt og einfaldað mál. Einnig erum við að vinna að nýrri virkni sem snýr að ljóslestri og læsileikamati sem mun líta dagsins ljós á næstu mánuðum á bæði vef og í forritaskilum.
Endilega hafið samband í gegnum api@mideind.is eða malstadur@mideind.is ef spurningar vakna varðandi forritaskil.
In the near future, we will be adding APIs for summarisation and plain language, among other things. We are also working on new functionality related to OCR and readability assessment, which will be launched in the coming months on both the web and in the APIs.
Please feel free to contact us via api@mideind.is or malstadur@mideind.is if you have any questions regarding the APIs.