{"id":50441454,"url":"https://github.com/theseyan/openai-zig","last_synced_at":"2026-05-31T19:32:49.199Z","repository":{"id":361430688,"uuid":"1254159321","full_name":"theseyan/openai-zig","owner":"theseyan","description":"OpenAI API client SDK for Zig","archived":false,"fork":false,"pushed_at":"2026-05-30T15:18:59.000Z","size":61,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-30T17:10:32.851Z","etag":null,"topics":["api","openai","zig"],"latest_commit_sha":null,"homepage":"https://theseyan.github.io/openai-zig/","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/theseyan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-30T07:59:59.000Z","updated_at":"2026-05-30T15:17:13.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/theseyan/openai-zig","commit_stats":null,"previous_names":["theseyan/openai-zig"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/theseyan/openai-zig","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theseyan%2Fopenai-zig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theseyan%2Fopenai-zig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theseyan%2Fopenai-zig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theseyan%2Fopenai-zig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/theseyan","download_url":"https://codeload.github.com/theseyan/openai-zig/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theseyan%2Fopenai-zig/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33746507,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","openai","zig"],"created_at":"2026-05-31T19:32:49.136Z","updated_at":"2026-05-31T19:32:49.188Z","avatar_url":"https://github.com/theseyan.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n \u003ch1\u003eopenai-zig\u003c/h1\u003e\n \u003cimg src=\"https://img.shields.io/badge/zig-0.16.0-%23F7A41D?logo=zig\u0026logoColor=%23F7A41D\" /\u003e\n \u003cimg src=\"https://img.shields.io/badge/License-MIT-blue\" /\u003e\n \u003cbr /\u003e\n \u003cbr /\u003e\n A Zig client for the OpenAI API.\n\u003c/div\u003e\n\n## Features\n\n- An easy-to-use interface, similar to `openai-python`\n- Built-in retry logic\n- Environment variable config support for API keys, organization IDs, project IDs, and base URLs\n- Chat completions, including streaming responses, image/audio/file inputs, and tool calling\n- Embeddings\n- Models\n- Files upload with `multipart/form-data`\n- Generic `request`, `requestStream`, and multipart request methods for missing endpoints\n\n## Installation\n\nTo install the latest version of `openai-zig`, run\n\n```bash\nzig fetch --save \"git+https://github.com/theseyan/openai-zig\"\n```\n\nTo install a specific version, run\n\n```bash\nzig fetch --save \"https://github.com/theseyan/openai-zig/archive/refs/tags/\u003cversion\u003e.tar.gz\"\n```\n\nThis branch targets Zig `0.16.0`.\n\nAnd add the following to your `build.zig`\n\n```zig\nconst openai = b.dependency(\"openai_zig\", .{\n    .target = target,\n    .optimize = optimize,\n});\n\nexe.root_module.addImport(\"openai\", openai.module(\"openai\"));\n```\n\n## Usage\n\n|✨ Documentation ✨||\n|--|--|\n|📙 openai-zig Docs |Generated with `zig build docs` |\n|📗 OpenAI API Docs|\u003chttps://platform.openai.com/docs/api-reference\u003e|\n\n### Client Configuration\n\n```zig\nconst openai = @import(\"openai\");\nconst OpenAI = openai.OpenAI;\n```\n\n```zig\npub fn main(init: std.process.Init) !void {\n    // Uses OPENAI_API_KEY from init.environ_map, or pass .api_key explicitly.\n    var client = try OpenAI.init(init.gpa, init.io, .{\n        .environ_map = init.environ_map,\n    });\n    defer client.deinit();\n}\n```\n\nFor applications that manage their own allocator and IO implementation:\n\n```zig\nvar io: std.Io.Threaded = .init(allocator, .{});\ndefer io.deinit();\n\nvar client = try OpenAI.init(allocator, io.io(), .{\n    .api_key = \"sk-...\",\n    // Optional; defaults to \"openai-zig/0.1.0\".\n    .user_agent = \"my-app/1.0\",\n});\ndefer client.deinit();\n```\n\n### Chat Completions\n\n#### Regular\n\n```zig\nconst ChatMessage = openai.ChatMessage;\n\nvar response = try client.chat.completions.create(.{\n    .model = \"gpt-4o\",\n    .messages = \u0026[_]ChatMessage{\n        .{\n            .role = \"user\",\n            .content = .{ .text = \"Hello, world!\" },\n        },\n    },\n});\n// This will free all the memory allocated for the response\ndefer response.deinit();\nif (response.choices[0].message.content) |content| {\n    std.log.debug(\"{s}\", .{content});\n}\n```\n\n#### Streamed Response\n\n```zig\nvar stream = try client.chat.completions.createStream(.{\n    .model = \"gpt-4o-mini\",\n    .messages = \u0026[_]ChatMessage{\n        .{\n            .role = \"user\",\n            .content = .{ .text = \"Write me a poem about lizards. Make it a paragraph or two.\" },\n        },\n    },\n});\ndefer stream.deinit();\n\nstd.debug.print(\"\\n\", .{});\nwhile (try stream.next()) |val| {\n    if (val.choices[0].delta.content) |content| {\n        std.debug.print(\"{s}\", .{content});\n    }\n}\nstd.debug.print(\"\\n\", .{});\n```\n\n#### Image Understanding\n\n```zig\nconst ChatContentPart = openai.ChatContentPart;\n\nconst parts = [_]ChatContentPart{\n    .{ .text = \"What is in this image?\" },\n    .{ .image_url = .{\n        .url = \"https://example.com/image.png\",\n        .detail = .high,\n    } },\n};\n\nvar response = try client.chat.completions.create(.{\n    .model = \"gpt-4o-mini\",\n    .messages = \u0026[_]ChatMessage{\n        .{\n            .role = \"user\",\n            .content = .{ .parts = \u0026parts },\n        },\n    },\n});\ndefer response.deinit();\n```\n\nFor local image bytes, pass a data URL in `ImageUrl.url`, such as `data:image/png;base64,...`.\nUse `openai.ImageUrl.dataUrl(allocator, \"image/png\", bytes)` to build one.\n\nThe same content-part API supports modern multimodal inputs:\n\n```zig\nconst parts = [_]ChatContentPart{\n    .{ .text = \"Summarize these inputs.\" },\n    .{ .input_audio = .{ .data = base64_wav, .format = \"wav\" } },\n    .{ .file = .{ .file_id = \"file_abc123\" } },\n};\n```\n\n#### Structured Outputs\n\n```zig\nconst CalendarEvent = struct {\n    name: []const u8,\n    participants: []const []const u8,\n    location: ?[]const u8 = null,\n};\n\nvar output = try openai.StructuredOutput(CalendarEvent).init(allocator, .{\n    .name = \"calendar_event\",\n    .description = \"Extract a calendar event.\",\n});\ndefer output.deinit();\n\nvar response = try client.chat.completions.create(.{\n    .model = \"gpt-4o-mini\",\n    .messages = \u0026[_]ChatMessage{\n        .{\n            .role = \"user\",\n            .content = .{ .text = \"Ada and Grace are reviewing the board plan.\" },\n        },\n    },\n    .response_format = output.responseFormat(),\n});\ndefer response.deinit();\n\nvar event = try output.parse(allocator, response.choices[0].message.content.?);\ndefer event.deinit();\nstd.log.debug(\"event: {s}\", .{event.value.name});\n```\n\n#### Tool Calling\n\n```zig\nconst ChatTool = openai.ChatTool;\nconst ToolCall = openai.ToolCall;\n\nconst tools = [_]ChatTool{\n    .{\n        .function = .{\n            .name = \"get_weather\",\n            .description = \"Get weather for a location\",\n            .parameters = schema_json_value,\n        },\n    },\n};\n\nvar response = try client.chat.completions.create(.{\n    .model = \"gpt-4o-mini\",\n    .messages = \u0026[_]ChatMessage{\n        .{\n            .role = \"user\",\n            .content = .{ .text = \"Weather in Paris?\" },\n        },\n    },\n    .tools = \u0026tools,\n    .tool_choice = .auto,\n});\ndefer response.deinit();\n\nif (response.choices[0].message.tool_calls) |tool_calls| {\n    const call = tool_calls[0];\n    if (call.function) |function| {\n        std.log.debug(\"Call {s} with {s}\", .{ function.name, function.arguments });\n    }\n}\n```\n\nSend tool results back with a tool message:\n\n```zig\nconst tool_calls = [_]ToolCall{\n    .{\n        .id = \"call_123\",\n        .function = .{\n            .name = \"get_weather\",\n            .arguments = \"{\\\"location\\\":\\\"Paris\\\"}\",\n        },\n    },\n};\n\nvar follow_up = try client.chat.completions.create(.{\n    .model = \"gpt-4o-mini\",\n    .messages = \u0026[_]ChatMessage{\n        .{\n            .role = \"assistant\",\n            .tool_calls = \u0026tool_calls,\n        },\n        .{\n            .role = \"tool\",\n            .content = .{ .text = \"{\\\"temperature\\\":\\\"18C\\\"}\" },\n            .tool_call_id = \"call_123\",\n        },\n    },\n});\ndefer follow_up.deinit();\n```\n\nFor idiomatic Zig tool functions, use the compile-time `Tools` helper. It generates function tool schemas from Zig argument structs and dispatches returned tool calls back to the registered functions.\n\n```zig\nconst WeatherArgs = struct {\n    location: []const u8,\n    unit: enum { c, f } = .c,\n};\nconst WeatherResult = struct {\n    temperature: []const u8,\n};\n\nfn getWeather(args: WeatherArgs) !WeatherResult {\n    _ = args;\n    return .{ .temperature = \"18C\" };\n}\n\nconst ToolSet = openai.Tools(.{\n    .{\n        .name = \"get_weather\",\n        .description = \"Get weather for a location\",\n        .function = getWeather,\n    },\n});\n\nvar tool_set = try ToolSet.init(allocator);\ndefer tool_set.deinit();\n\nvar response = try client.chat.completions.create(.{\n    .model = \"gpt-4o-mini\",\n    .messages = \u0026messages,\n    .tools = tool_set.definitions,\n});\ndefer response.deinit();\n\nif (response.choices[0].message.tool_calls) |tool_calls| {\n    const tool_messages = try tool_set.runAll(allocator, tool_calls);\n    defer tool_messages.deinit();\n    // Send `tool_messages.messages` in the next chat completion request.\n}\n```\n\n### Embeddings\n\n```zig\nconst inputs = [_][]const u8{ \"Hello\", \"Foo\", \"Bar\" };\nconst response = try client.embeddings.create(.{\n    .model = \"text-embedding-3-small\",\n    .input = .{ .texts = \u0026inputs },\n    .encoding_format = \"float\",\n});\n// Don't forget to free resources!\ndefer response.deinit();\nconst vector = response.data[0].embedding.float;\nstd.log.debug(\"Model: {s}\\nNumber of Embeddings: {d}\\nDimensions of Embeddings: {d}\", .{\n    response.model, response.data.len, vector.len,\n});\n```\n\n### Files\n\n```zig\nvar response = try client.files.create(.{\n    .file = .{\n        .filename = \"training.jsonl\",\n        .content = file_bytes,\n        .content_type = \"application/jsonl\",\n    },\n    .purpose = .@\"fine-tune\",\n});\ndefer response.deinit();\n\nstd.log.debug(\"Uploaded file: {s}\", .{response.id});\n```\n\n`files.create` sends `multipart/form-data`. Optional expiration metadata is supported with `.expires_after`.\n\n```zig\nvar files = try client.files.list(.{\n    .purpose = \"fine-tune\",\n    .limit = 20,\n    .order = .desc,\n});\ndefer files.deinit();\n\nvar file = try client.files.retrieve(files.data[0].id);\ndefer file.deinit();\n\nconst contents = try client.files.content(file.id, 10 * 1024 * 1024);\ndefer client.allocator.free(contents);\n\nvar deleted = try client.files.delete(file.id);\ndefer deleted.deinit();\n```\n\n### Models\n\n#### Get model details\n\n```zig\nvar response = try client.models.retrieve(\"gpt-4o\");\ndefer response.deinit();\nstd.log.debug(\"Model is owned by '{s}'\", .{response.owned_by});\n```\n\n#### List all models\n\n```zig\nvar response = try client.models.list();\ndefer response.deinit();\nstd.log.debug(\"The first model you have available is '{s}'\", .{response.data[0].id});\n```\n\n#### Delete a fine-tuned model\n\n```zig\nvar deleted = try client.models.delete(\"ft:gpt-4o-mini:org:custom:abc\");\ndefer deleted.deinit();\nstd.log.debug(\"Deleted: {}\", .{deleted.deleted});\n```\n\n## Configuring Logging\n\nBy default all logs are enabled for your entire application.\nTo configure your application, and set the log level for `openai-zig`, include the following in your `main.zig`.\n\n```zig\npub const std_options = std.Options{\n    .log_level = .debug, // this sets your app level log config\n    .log_scope_levels = \u0026[_]std.log.ScopeLevel{\n        .{\n            .scope = .openai,\n            .level = .info, // set to .debug, .warn, .info, or .err\n        },\n    },\n};\n```\n\nAll logs in `openai-zig` use the scope `.openai`, so if you don't want to see debug/info logs of the requests being sent, set `.level = .err`. This will only display when an error occurs that the client can't recover from.\n\n## Contributions\n\nContributions are welcome and encouraged! Submit an issue for any bugs/feature requests and open a PR if you tackled one of them!\n\n## Building Docs\n\n```bash\nzig build\nzig build test\nzig build docs\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheseyan%2Fopenai-zig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftheseyan%2Fopenai-zig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheseyan%2Fopenai-zig/lists"}