diff --git a/epicardium/api/caller.c b/epicardium/api/caller.c
index f1ba675fa98b03d0ee6411e2a0271829174d809d..7c52d28051250850009871c460ce29561caaaf48 100644
--- a/epicardium/api/caller.c
+++ b/epicardium/api/caller.c
@@ -53,3 +53,25 @@ void *_api_call_transact(void *buffer)
 
 	return API_CALL_MEM->buffer;
 }
+
+int api_fetch_args(char *buf, size_t cnt)
+{
+	if (API_CALL_MEM->id != 0) {
+		/*
+		 * When any call happened before the args are fetched, they are
+		 * overwritten and no longer accessible.
+		 */
+		return (-1);
+	}
+
+	if (API_CALL_MEM->buffer[0x20] == '\0') {
+		return 0;
+	}
+
+	int i;
+	for (i = 0; i < cnt && API_CALL_MEM->buffer[i + 0x20] != '\0'; i++) {
+		buf[i] = API_CALL_MEM->buffer[i + 0x20];
+	}
+
+	return i - 1;
+}
diff --git a/epicardium/api/caller.h b/epicardium/api/caller.h
index d9192c85e133502c005d2e868eebbf39598dd7ff..93bd3f3d71fb88cc81481c939af6b18fb6e496b0 100644
--- a/epicardium/api/caller.h
+++ b/epicardium/api/caller.h
@@ -27,3 +27,12 @@ void *_api_call_start(api_id_t id, uintptr_t size);
  *   - Pointer to a buffer containing the return value
  */
 void *_api_call_transact(void *buffer);
+
+/*
+ * Fetch arguments from the API buffer.  This function will only work properly
+ * directly after startup of core 1.  If api_fetch_args() is called after other
+ * calls have already happened, it will return -1.
+ *
+ * Otherwise it will return the length of data which was read.
+ */
+int api_fetch_args(char *buf, size_t cnt);
diff --git a/epicardium/api/dispatcher.c b/epicardium/api/dispatcher.c
index 4675c8d4f53f1e90b2d0809cb5979589e7a58af1..730579758e22bd66bd84520a4006bb0acb8ebe17 100644
--- a/epicardium/api/dispatcher.c
+++ b/epicardium/api/dispatcher.c
@@ -1,7 +1,15 @@
-#include <stdlib.h>
-#include "sema.h"
 #include "api/dispatcher.h"
+
 #include "max32665.h"
+#include "sema.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/* This function is defined by the generated dispatcher code */
+void __api_dispatch_call(api_id_t id, void *buffer);
+
+static volatile bool event_ready = false;
 
 int api_dispatcher_init()
 {
@@ -20,8 +28,6 @@ int api_dispatcher_init()
 	return ret;
 }
 
-static bool event_ready = false;
-
 bool api_dispatcher_poll_once()
 {
 	if (event_ready) {
@@ -68,3 +74,15 @@ api_id_t api_dispatcher_exec()
 
 	return id;
 }
+
+void api_prepare_args(char *args)
+{
+	/*
+	 * The args are stored with an offset of 0x20 to make sure they won't
+	 * collide with any integer return value of API calls like epic_exec().
+	 */
+	API_CALL_MEM->id = 0;
+	for (int i = 0; i <= strlen(args); i++) {
+		API_CALL_MEM->buffer[i + 0x20] = args[i];
+	}
+}
diff --git a/epicardium/api/dispatcher.h b/epicardium/api/dispatcher.h
index a67aa0c40df25968f51809da9c4401b5c3ef1a7a..1294592d79eedf1bec49cc68525c81e306248c55 100644
--- a/epicardium/api/dispatcher.h
+++ b/epicardium/api/dispatcher.h
@@ -22,5 +22,9 @@ bool api_dispatcher_poll();
  */
 api_id_t api_dispatcher_exec();
 
-/* This function is defined by the generated dispatcher code */
-void __api_dispatch_call(api_id_t id, void *buffer);
+/*
+ * Fill the API buffer with data for l0dable/pycardium startup.
+ *
+ * The data is a NULL-terminated string.
+ */
+void api_prepare_args(char *args);
diff --git a/pycardium/main.c b/pycardium/main.c
index 60c86093af0e319a6367cb05957aec40dc8d7eb8..78450da0bfe2182502a21b390ca094c9ac10ec79 100644
--- a/pycardium/main.c
+++ b/pycardium/main.c
@@ -1,4 +1,5 @@
 #include "epicardium.h"
+#include "api/caller.h"
 #include "mphalport.h"
 #include "card10-version.h"
 
@@ -24,10 +25,19 @@ static const char header[] =
 
 int main(void)
 {
-	epic_uart_write_str(header, sizeof(header));
+	char script_name[128] = { 0 };
+	int cnt = api_fetch_args(script_name, sizeof(script_name));
 
 	pycardium_hal_init();
 
+	epic_uart_write_str(header, sizeof(header));
+
+	if (cnt < 0) {
+		printf("pycardium: Error fetching args: %d\n", cnt);
+	} else if (cnt > 0) {
+		printf("  Loading %s ...\n", script_name);
+	}
+
 	mp_stack_set_top(&__StackTop);
 	mp_stack_set_limit((mp_int_t)&__StackLimit);
 
@@ -35,8 +45,13 @@ int main(void)
 		gc_init(&__HeapBase + 1024 * 10, &__HeapLimit);
 
 		mp_init();
-		pyexec_file_if_exists("main.py");
+
+		if (cnt > 0) {
+			pyexec_file_if_exists(script_name);
+		}
+
 		pyexec_friendly_repl();
+
 		mp_deinit();
 	}
 }