1 line
71 KiB
JSON
1 line
71 KiB
JSON
{"openapi":"3.0.0","info":{"title":"Unkey Api","version":"1.0.0"},"servers":[{"url":"https://api.unkey.dev","description":"Production"}],"components":{"securitySchemes":{"bearerAuth":{"bearerFormat":"root key","type":"http","scheme":"bearer"}},"schemas":{"ErrBadRequest":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["BAD_REQUEST"],"description":"A machine readable error code.","example":"BAD_REQUEST"},"docs":{"type":"string","description":"A link to our documentation with more details about this error code","example":"https://unkey.dev/docs/api-reference/errors/code/BAD_REQUEST"},"message":{"type":"string","description":"A human readable explanation of what went wrong"},"requestId":{"type":"string","description":"Please always include the requestId in your error report","example":"req_1234"}},"required":["code","docs","message","requestId"]}},"required":["error"]},"ErrUnauthorized":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHORIZED"],"description":"A machine readable error code.","example":"UNAUTHORIZED"},"docs":{"type":"string","description":"A link to our documentation with more details about this error code","example":"https://unkey.dev/docs/api-reference/errors/code/UNAUTHORIZED"},"message":{"type":"string","description":"A human readable explanation of what went wrong"},"requestId":{"type":"string","description":"Please always include the requestId in your error report","example":"req_1234"}},"required":["code","docs","message","requestId"]}},"required":["error"]},"ErrForbidden":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"A machine readable error code.","example":"FORBIDDEN"},"docs":{"type":"string","description":"A link to our documentation with more details about this error code","example":"https://unkey.dev/docs/api-reference/errors/code/FORBIDDEN"},"message":{"type":"string","description":"A human readable explanation of what went wrong"},"requestId":{"type":"string","description":"Please always include the requestId in your error report","example":"req_1234"}},"required":["code","docs","message","requestId"]}},"required":["error"]},"ErrNotFound":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"A machine readable error code.","example":"NOT_FOUND"},"docs":{"type":"string","description":"A link to our documentation with more details about this error code","example":"https://unkey.dev/docs/api-reference/errors/code/NOT_FOUND"},"message":{"type":"string","description":"A human readable explanation of what went wrong"},"requestId":{"type":"string","description":"Please always include the requestId in your error report","example":"req_1234"}},"required":["code","docs","message","requestId"]}},"required":["error"]},"ErrConflict":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["CONFLICT"],"description":"A machine readable error code.","example":"CONFLICT"},"docs":{"type":"string","description":"A link to our documentation with more details about this error code","example":"https://unkey.dev/docs/api-reference/errors/code/CONFLICT"},"message":{"type":"string","description":"A human readable explanation of what went wrong"},"requestId":{"type":"string","description":"Please always include the requestId in your error report","example":"req_1234"}},"required":["code","docs","message","requestId"]}},"required":["error"]},"ErrTooManyRequests":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["TOO_MANY_REQUESTS"],"description":"A machine readable error code.","example":"TOO_MANY_REQUESTS"},"docs":{"type":"string","description":"A link to our documentation with more details about this error code","example":"https://unkey.dev/docs/api-reference/errors/code/TOO_MANY_REQUESTS"},"message":{"type":"string","description":"A human readable explanation of what went wrong"},"requestId":{"type":"string","description":"Please always include the requestId in your error report","example":"req_1234"}},"required":["code","docs","message","requestId"]}},"required":["error"]},"ErrInternalServerError":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["INTERNAL_SERVER_ERROR"],"description":"A machine readable error code.","example":"INTERNAL_SERVER_ERROR"},"docs":{"type":"string","description":"A link to our documentation with more details about this error code","example":"https://unkey.dev/docs/api-reference/errors/code/INTERNAL_SERVER_ERROR"},"message":{"type":"string","description":"A human readable explanation of what went wrong"},"requestId":{"type":"string","description":"Please always include the requestId in your error report","example":"req_1234"}},"required":["code","docs","message","requestId"]}},"required":["error"]},"Key":{"type":"object","properties":{"id":{"type":"string","description":"The id of the key","example":"key_1234"},"start":{"type":"string","description":"The first few characters of the key to visually identify it","example":"sk_5j1"},"workspaceId":{"type":"string","description":"The id of the workspace that owns the key","example":"ws_1234"},"apiId":{"type":"string","description":"The id of the api that this key is for","example":"api_1234"},"name":{"type":"string","description":"The name of the key, give keys a name to easily identify their purpose","example":"Customer X"},"ownerId":{"type":"string","description":"The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API.","example":"user_123"},"meta":{"type":"object","additionalProperties":{"nullable":true},"description":"Any additional metadata you want to store with the key","example":{"roles":["admin","user"],"stripeCustomerId":"cus_1234"}},"createdAt":{"type":"number","description":"The unix timestamp in milliseconds when the key was created","example":0},"deletedAt":{"type":"number","description":"The unix timestamp in milliseconds when the key was deleted. We don't delete the key outright, you can restore it later.","example":0},"expires":{"type":"number","description":"The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.","example":0},"remaining":{"type":"number","description":"The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit.","example":1000},"refill":{"type":"object","properties":{"interval":{"type":"string","enum":["daily","monthly"],"description":"Determines the rate at which verifications will be refilled.","example":"daily"},"amount":{"type":"integer","description":"Resets `remaining` to this value every interval.","example":100},"lastRefillAt":{"type":"number","description":"The unix timestamp in miliseconds when the key was last refilled.","example":100}},"required":["interval","amount"],"description":"Unkey allows you to refill remaining verifications on a key on a regular interval.","example":{"interval":"daily","amount":10}},"ratelimit":{"type":"object","properties":{"type":{"type":"string","enum":["fast","consistent"],"default":"fast","description":"Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate.","externalDocs":{"description":"Learn more","url":"https://unkey.dev/docs/features/ratelimiting"}},"limit":{"type":"integer","minimum":1,"description":"The total amount of burstable requests."},"refillRate":{"type":"integer","minimum":1,"description":"How many tokens to refill during each refillInterval."},"refillInterval":{"type":"integer","minimum":1,"description":"Determines the speed at which tokens are refilled, in milliseconds."}},"required":["limit","refillRate","refillInterval"],"description":"Unkey comes with per-key ratelimiting out of the box.","example":{"type":"fast","limit":10,"refillRate":1,"refillInterval":60}},"roles":{"type":"array","items":{"type":"string"},"description":"All roles this key belongs to","example":["admin","finance"]},"permissions":{"type":"array","items":{"type":"string"},"description":"All permissions this key has","example":["domain.dns.create_record","finance.read_receipt"]},"enabled":{"type":"boolean","description":"Sets if key is enabled or disabled. Disabled keys are not valid.","example":true}},"required":["id","start","workspaceId"]},"V1KeysVerifyKeyResponse":{"type":"object","properties":{"keyId":{"type":"string","description":"The id of the key","example":"key_1234"},"valid":{"type":"boolean","description":"Whether the key is valid or not.\nA key could be invalid for a number of reasons, for example if it has expired, has no more verifications left or if it has been deleted.","example":true},"name":{"type":"string","description":"The name of the key, give keys a name to easily identifiy their purpose","example":"Customer X"},"ownerId":{"type":"string","description":"The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API.","example":"user_123"},"meta":{"type":"object","additionalProperties":{"nullable":true},"description":"Any additional metadata you want to store with the key","example":{"roles":["admin","user"],"stripeCustomerId":"cus_1234"}},"expires":{"type":"number","description":"The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.","example":123},"ratelimit":{"type":"object","properties":{"limit":{"type":"number","description":"Maximum number of requests that can be made inside a window","example":10},"remaining":{"type":"number","description":"Remaining requests after this verification","example":9},"reset":{"type":"number","description":"Unix timestamp in milliseconds when the ratelimit will reset","example":3600000}},"required":["limit","remaining","reset"],"description":"The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit.","example":{"limit":10,"remaining":9,"reset":3600000}},"remaining":{"type":"number","description":"The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit.","example":1000},"code":{"type":"string","enum":["NOT_FOUND","FORBIDDEN","USAGE_EXCEEDED","RATE_LIMITED","UNAUTHORIZED","DISABLED","INSUFFICIENT_PERMISSIONS"],"description":"If the key is invalid this field will be set to the reason why it is invalid.\nPossible values are:\n- NOT_FOUND: the key does not exist or has expired\n- FORBIDDEN: the key is not allowed to access the api\n- USAGE_EXCEEDED: the key has exceeded its request limit\n- RATE_LIMITED: the key has been ratelimited\n- UNAUTHORIZED: the key is not authorized\n- DISABLED: the key is disabled\n- INSUFFICIENT_PERMISSIONS: you do not have the required permissions to perform this action\n"},"enabled":{"type":"boolean","description":"Sets the key to be enabled or disabled. Disabled keys will not verify."},"permissions":{"type":"array","items":{"type":"string"},"description":"A list of all the permissions this key is connected to.","example":["dns.record.update","dns.record.delete"]},"environment":{"type":"string","description":"The environment of the key, this is what what you set when you crated the key","example":"test"}},"required":["valid"]},"V1KeysVerifyKeyRequest":{"type":"object","properties":{"apiId":{"type":"string","description":"The id of the api where the key belongs to. This is optional for now but will be required soon.\nThe key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail.","example":"api_1234"},"key":{"type":"string","minLength":1,"description":"The key to verify","example":"sk_1234"},"authorization":{"type":"object","properties":{"permissions":{"type":"object","description":"A query for which permissions you require","example":{"or":[{"and":["dns.record.read","dns.record.update"]},"admin"]}}},"description":"Perform RBAC checks"}},"required":["key"]}},"parameters":{}},"paths":{"/v1/liveness":{"get":{"responses":{"200":{"description":"The configured services and their status","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":"The status of the server"},"services":{"type":"object","properties":{"metrics":{"type":"string","description":"The name of the connected metrics service","example":"AxiomMetrics"},"logger":{"type":"string","description":"The name of the connected logger service","example":"AxiomLogger or ConsoleLogger"},"ratelimit":{"type":"string","description":"The name of the connected ratelimit service"},"usagelimit":{"type":"string","description":"The name of the connected usagelimit service"},"analytics":{"type":"string","description":"The name of the connected analytics service"}},"required":["metrics","logger","ratelimit","usagelimit","analytics"]}},"required":["status","services"]}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/keys.getKey":{"get":{"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"The id of the key to fetch","example":"key_1234"},"required":true,"name":"keyId","in":"query"}],"responses":{"200":{"description":"The configuration for a single key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Key"}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/keys.deleteKey":{"post":{"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"keyId":{"type":"string","minLength":1,"description":"The id of the key to revoke","example":"key_1234"}},"required":["keyId"]}}}},"responses":{"200":{"description":"The key was successfully revoked, it may take up to 30s for this to take effect in all regions","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/keys.createKey":{"post":{"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"apiId":{"type":"string","description":"Choose an `API` where this key should be created.","example":"api_123"},"prefix":{"type":"string","maxLength":8,"description":"To make it easier for your users to understand which product an api key belongs to, you can add prefix them.\n\nFor example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_.\n\nThe underscore is automatically added if you are defining a prefix, for example: \"prefix\": \"abc\" will result in a key like abc_xxxxxxxxx\n"},"name":{"type":"string","description":"The name for your Key. This is not customer facing.","example":"my key"},"byteLength":{"type":"integer","minimum":16,"maximum":255,"default":16,"description":"The byte length used to generate your key determines its entropy as well as its length. Higher is better, but keys become longer and more annoying to handle. The default is 16 bytes, or 2^^128 possible combinations."},"ownerId":{"type":"string","description":"Your user’s Id. This will provide a link between Unkey and your customer record.\nWhen validating a key, we will return this back to you, so you can clearly identify your user from their api key.","example":"team_123"},"meta":{"type":"object","additionalProperties":{"nullable":true},"description":"This is a place for dynamic meta data, anything that feels useful for you should go here","example":{"billingTier":"PRO","trialEnds":"2023-06-16T17:16:37.161Z"}},"roles":{"type":"array","items":{"type":"string","minLength":1,"maxLength":512},"description":"A list of roles that this key should have. If the role does not exist, an error is thrown","example":["admin","finance"]},"expires":{"type":"integer","description":"You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again.","example":1623869797161},"remaining":{"type":"integer","description":"You can limit the number of requests a key can make. Once a key reaches 0 remaining requests, it will automatically be disabled and is no longer valid unless you update it.","example":1000,"externalDocs":{"description":"Learn more","url":"https://unkey.dev/docs/features/remaining"}},"refill":{"type":"object","properties":{"interval":{"type":"string","enum":["daily","monthly"],"description":"Unkey will automatically refill verifications at the set interval."},"amount":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"The number of verifications to refill for each occurrence is determined individually for each key."}},"required":["interval","amount"],"description":"Unkey enables you to refill verifications for each key at regular intervals.","example":{"interval":"daily","amount":100}},"ratelimit":{"type":"object","properties":{"type":{"type":"string","enum":["fast","consistent"],"default":"fast","description":"Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate.","externalDocs":{"description":"Learn more","url":"https://unkey.dev/docs/features/ratelimiting"}},"limit":{"type":"integer","minimum":1,"description":"The total amount of burstable requests."},"refillRate":{"type":"integer","minimum":1,"description":"How many tokens to refill during each refillInterval."},"refillInterval":{"type":"integer","minimum":1,"description":"Determines the speed at which tokens are refilled, in milliseconds."}},"required":["limit","refillRate","refillInterval"],"description":"Unkey comes with per-key ratelimiting out of the box.","example":{"type":"fast","limit":10,"refillRate":1,"refillInterval":60}},"enabled":{"type":"boolean","default":true,"description":"Sets if key is enabled or disabled. Disabled keys are not valid.","example":false},"environment":{"type":"string","maxLength":256,"description":"Environments allow you to divide your keyspace. \n\nSome applications like Stripe, Clerk, WorkOS and others have a concept of \"live\" and \"test\" keys to \ngive the developer a way to develop their own application without the risk of modifying real world \nresources.\n\nWhen you set an environment, we will return it back to you when validating the key, so you can\nhandle it correctly.\n "}},"required":["apiId"]}}}},"responses":{"200":{"description":"The configuration for an api","content":{"application/json":{"schema":{"type":"object","properties":{"keyId":{"type":"string","description":"The id of the key. This is not a secret and can be stored as a reference if you wish. You need the keyId to update or delete a key later.","example":"key_123"},"key":{"type":"string","description":"The newly created api key, do not store this on your own system but pass it along to your user.","example":"prefix_xxxxxxxxx"}},"required":["keyId","key"]}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/keys.verifyKey":{"post":{"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1KeysVerifyKeyRequest"}}}},"responses":{"200":{"description":"The verification result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1KeysVerifyKeyResponse"}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/keys.updateKey":{"post":{"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"keyId":{"type":"string","description":"The id of the key you want to modify","example":"key_123"},"name":{"type":"string","nullable":true,"description":"The name of the key","example":"Customer X"},"ownerId":{"type":"string","nullable":true,"description":"The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API.","example":"user_123"},"meta":{"type":"object","nullable":true,"additionalProperties":{"nullable":true},"description":"Any additional metadata you want to store with the key","example":{"roles":["admin","user"],"stripeCustomerId":"cus_1234"}},"expires":{"type":"number","nullable":true,"description":"The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.","example":0},"ratelimit":{"type":"object","nullable":true,"properties":{"type":{"type":"string","enum":["fast","consistent"],"description":"Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate.","externalDocs":{"description":"Learn more","url":"https://unkey.dev/docs/features/ratelimiting"}},"limit":{"type":"integer","minimum":1,"description":"The total amount of burstable requests."},"refillRate":{"type":"integer","minimum":1,"description":"How many tokens to refill during each refillInterval."},"refillInterval":{"type":"integer","minimum":1,"description":"Determines the speed at which tokens are refilled, in milliseconds."}},"required":["type","limit","refillRate","refillInterval"],"description":"Unkey comes with per-key ratelimiting out of the box. Set `null` to disable.","example":{"type":"fast","limit":10,"refillRate":1,"refillInterval":60}},"remaining":{"type":"number","nullable":true,"description":"The number of requests that can be made with this key before it becomes invalid. Set `null` to disable.","example":1000},"refill":{"type":"object","nullable":true,"properties":{"interval":{"type":"string","enum":["daily","monthly"],"description":"Unkey will automatically refill verifications at the set interval. If null is used the refill functionality will be removed from the key."},"amount":{"type":"integer","minimum":1,"description":"The amount of verifications to refill for each occurrence is determined individually for each key."}},"required":["interval","amount"],"description":"Unkey enables you to refill verifications for each key at regular intervals.","example":{"interval":"daily","amount":100}},"enabled":{"type":"boolean","description":"Set if key is enabled or disabled. If disabled, the key cannot be used to verify.","example":true}},"required":["keyId"]}}}},"responses":{"200":{"description":"The key was successfully updated, it may take up to 30s for this to take effect in all regions","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/keys.updateRemaining":{"post":{"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"keyId":{"type":"string","description":"The id of the key you want to modify","example":"key_123"},"op":{"type":"string","enum":["increment","decrement","set"],"description":"The operation you want to perform on the remaining count"},"value":{"type":"integer","nullable":true,"description":"The value you want to set, add or subtract the remaining count by","example":1}},"required":["keyId","op","value"]}}}},"responses":{"200":{"description":"The configuration for an api","content":{"application/json":{"schema":{"type":"object","properties":{"remaining":{"type":"integer","nullable":true,"description":"The number of remaining requests for this key after updating it. `null` means unlimited.","example":100}},"required":["remaining"]}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/keys.getVerifications":{"get":{"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The id of the key to fetch, either `keyId` or `ownerId` must be provided","example":"key_1234"},"required":false,"name":"keyId","in":"query"},{"schema":{"type":"string","description":"The owner id to fetch keys for, either `keyId` or `ownerId` must be provided","example":"chronark"},"required":false,"name":"ownerId","in":"query"},{"schema":{"type":"integer","nullable":true,"description":"The start of the period to fetch usage for as unix milliseconds timestamp","example":1620000000000},"required":false,"name":"start","in":"query"},{"schema":{"type":"integer","nullable":true,"description":"The end of the period to fetch usage for as unix milliseconds timestamp","example":1620000000000},"required":false,"name":"end","in":"query"},{"schema":{"type":"string","enum":["day"],"default":"day","description":"The granularity of the usage data to fetch, currently only `day` is supported","example":"day"},"required":false,"name":"granularity","in":"query"}],"responses":{"200":{"description":"Usage numbers over time","content":{"application/json":{"schema":{"type":"object","properties":{"verifications":{"type":"array","items":{"type":"object","properties":{"time":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"The timestamp of the usage data","example":1620000000000},"success":{"type":"number","description":"The number of successful requests","example":100},"rateLimited":{"type":"number","description":"The number of requests that were rate limited","example":10},"usageExceeded":{"type":"number","description":"The number of requests that exceeded the usage limit","example":0}},"required":["time","success","rateLimited","usageExceeded"]}}},"required":["verifications"]}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/apis.getApi":{"get":{"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"The id of the api to fetch","example":"api_1234"},"required":true,"name":"apiId","in":"query"}],"responses":{"200":{"description":"The configuration for an api","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The id of the key","example":"key_1234"},"workspaceId":{"type":"string","description":"The id of the workspace that owns the api","example":"ws_1234"},"name":{"type":"string","description":"The name of the api. This is internal and your users will not see this.","example":"Unkey - Production"}},"required":["id","workspaceId"]}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/apis.createApi":{"post":{"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":3,"description":"The name for your API. This is not customer facing.","example":"my-api"}},"required":["name"]}}}},"responses":{"200":{"description":"The configuration for an api","content":{"application/json":{"schema":{"type":"object","properties":{"apiId":{"type":"string","description":"The id of the api","example":"api_134"}},"required":["apiId"]}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/apis.listKeys":{"get":{"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"The id of the api to fetch","example":"api_1234"},"required":true,"name":"apiId","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":100,"description":"The maximum number of keys to return","example":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","description":"Use this to fetch the next page of results. A new cursor will be returned in the response if there are more results."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"string","minLength":1,"description":"If provided, this will only return keys where the `ownerId` matches."},"required":false,"name":"ownerId","in":"query"}],"responses":{"200":{"description":"The configuration for an api","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/Key"}},"cursor":{"type":"string","description":"The cursor to use for the next page of results, if no cursor is returned, there are no more results","example":"eyJrZXkiOiJrZXlfMTIzNCJ9"},"total":{"type":"integer","description":"The total number of keys for this api"}},"required":["keys","total"]}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/apis.deleteApi":{"post":{"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"apiId":{"type":"string","minLength":1,"description":"The id of the api to delete","example":"api_1234"}},"required":["apiId"]}}}},"responses":{"200":{"description":"The api was successfully deleted, it may take up to 30s for this to take effect in all regions","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/ratelimits.limit":{"post":{"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"namespace":{"type":"string","default":"default","description":"Namespaces group different limits together for better analytics. You might have a namespace for your public API and one for internal tRPC routes.","example":"email.outbound"},"identifier":{"type":"string","description":"Identifier of your user, this can be their userId, an email, an ip or anything else.","example":"user_123"},"limit":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"How many requests may pass in a given window.","example":10},"duration":{"type":"integer","minimum":1000,"description":"The window duration in milliseconds","example":60000},"cost":{"type":"integer","minimum":1,"default":1,"description":"Expensive requests may use up more tokens. You can specify a cost to the request here and we'll deduct this many tokens in the current window. If there are not enough tokens left, the request is denied.","example":2},"async":{"type":"boolean","default":false,"description":"Async will return a response immediately, lowering latency at the cost of accuracy."},"meta":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"boolean"},{"type":"number"},{"nullable":true},{"nullable":true}]},"description":"Attach any metadata to this request"},"resources":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"The type of resource","example":"organization"},"id":{"type":"string","description":"The unique identifier for the resource","example":"org_123"},"name":{"type":"string","description":"A human readable name for this resource","example":"unkey"},"meta":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"boolean"},{"type":"number"},{"nullable":true},{"nullable":true}]},"description":"Attach any metadata to this resources"}},"required":["type","id"]},"description":"Resources that are about to be accessed by the user","example":[{"type":"project","id":"p_123","name":"dub"}]}},"required":["identifier","limit","duration"]}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Returns true if the request should be processed, false if it was rejected.","example":true},"limit":{"type":"number","description":"How many requests are allowed within a window.","example":10},"remaining":{"type":"number","description":"How many requests can still be made in the current window.","example":9},"reset":{"type":"number","description":"A unix millisecond timestamp when the limits reset.","example":1709804263654}},"required":["success","limit","remaining","reset"]}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/keys":{"post":{"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"apiId":{"type":"string","description":"Choose an `API` where this key should be created.","example":"api_123"},"prefix":{"type":"string","maxLength":8,"description":"To make it easier for your users to understand which product an api key belongs to, you can add prefix them.\n\nFor example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_.\n\nThe underscore is automatically added if you are defining a prefix, for example: \"prefix\": \"abc\" will result in a key like abc_xxxxxxxxx\n"},"name":{"type":"string","description":"The name for your Key. This is not customer facing.","example":"my key"},"byteLength":{"type":"integer","minimum":16,"maximum":255,"default":16,"description":"The byte length used to generate your key determines its entropy as well as its length. Higher is better, but keys become longer and more annoying to handle. The default is 16 bytes, or 2^^128 possible combinations."},"ownerId":{"type":"string","description":"Your user’s Id. This will provide a link between Unkey and your customer record.\nWhen validating a key, we will return this back to you, so you can clearly identify your user from their api key.","example":"team_123"},"meta":{"type":"object","additionalProperties":{"nullable":true},"description":"This is a place for dynamic meta data, anything that feels useful for you should go here","example":{"billingTier":"PRO","trialEnds":"2023-06-16T17:16:37.161Z"}},"expires":{"type":"integer","description":"You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again.","example":1623869797161},"remaining":{"type":"integer","description":"You can limit the number of requests a key can make. Once a key reaches 0 remaining requests, it will automatically be disabled and is no longer valid unless you update it.","example":1000,"externalDocs":{"description":"Learn more","url":"https://unkey.dev/docs/features/remaining"}},"ratelimit":{"type":"object","properties":{"type":{"type":"string","enum":["fast","consistent"],"default":"fast","description":"Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate.","externalDocs":{"description":"Learn more","url":"https://unkey.dev/docs/features/ratelimiting"}},"limit":{"type":"integer","minimum":1,"description":"The total amount of burstable requests."},"refillRate":{"type":"integer","minimum":1,"description":"How many tokens to refill during each refillInterval."},"refillInterval":{"type":"integer","minimum":1,"description":"Determines the speed at which tokens are refilled, in milliseconds."}},"required":["limit","refillRate","refillInterval"],"description":"Unkey comes with per-key ratelimiting out of the box.","example":{"type":"fast","limit":10,"refillRate":1,"refillInterval":60}}},"required":["apiId"]}}}},"responses":{"200":{"description":"The configuration for an api","content":{"application/json":{"schema":{"type":"object","properties":{"keyId":{"type":"string","description":"The id of the key. This is not a secret and can be stored as a reference if you wish. You need the keyId to update or delete a key later.","example":"key_123"},"key":{"type":"string","description":"The newly created api key, do not store this on your own system but pass it along to your user.","example":"prefix_xxxxxxxxx"}},"required":["keyId","key"]}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/keys/verify":{"post":{"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"apiId":{"type":"string","description":"The id of the api where the key belongs to. This is optional for now but will be required soon.\nThe key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail.","example":"api_1234"},"key":{"type":"string","minLength":1,"description":"The key to verify","example":"sk_1234"}},"required":["key"]}}}},"responses":{"200":{"description":"The verification result","content":{"application/json":{"schema":{"type":"object","properties":{"keyId":{"type":"string","description":"The id of the key","example":"key_1234"},"valid":{"type":"boolean","description":"Whether the key is valid or not.\nA key could be invalid for a number of reasons, for example if it has expired, has no more verifications left or if it has been deleted.","example":true},"name":{"type":"string","description":"The name of the key, give keys a name to easily identifiy their purpose","example":"Customer X"},"ownerId":{"type":"string","description":"The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API.","example":"user_123"},"meta":{"type":"object","additionalProperties":{"nullable":true},"description":"Any additional metadata you want to store with the key","example":{"roles":["admin","user"],"stripeCustomerId":"cus_1234"}},"createdAt":{"type":"number","description":"The unix timestamp in milliseconds when the key was created","example":0},"deletedAt":{"type":"number","description":"The unix timestamp in milliseconds when the key was deleted. We don't delete the key outright, you can restore it later.","example":0},"expires":{"type":"number","description":"The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.","example":123},"ratelimit":{"type":"object","properties":{"limit":{"type":"number","description":"Maximum number of requests that can be made inside a window","example":10},"remaining":{"type":"number","description":"Remaining requests after this verification","example":9},"reset":{"type":"number","description":"Unix timestamp in milliseconds when the ratelimit will reset","example":3600000}},"required":["limit","remaining","reset"],"description":"The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit.","example":{"limit":10,"remaining":9,"reset":3600000}},"remaining":{"type":"number","description":"The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit.","example":1000},"code":{"type":"string","enum":["NOT_FOUND","FORBIDDEN","USAGE_EXCEEDED","RATE_LIMITED","UNAUTHORIZED","DISABLED","INSUFFICIENT_PERMISSIONS"],"description":"If the key is invalid this field will be set to the reason why it is invalid.\nPossible values are:\n- NOT_FOUND: the key does not exist or has expired\n- FORBIDDEN: the key is not allowed to access the api\n- USAGE_EXCEEDED: the key has exceeded its request limit\n- RATE_LIMITED: the key has been ratelimited,\n- INSUFFICIENT_PERMISSIONS: you do not have the required permissions to perform this action\n","example":"NOT_FOUND"}},"required":["valid"]}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}},"/v1/apis/{apiId}/keys":{"get":{"parameters":[{"schema":{"type":"string","minLength":1,"description":"The id of the api to fetch","example":"api_1234"},"required":true,"name":"apiId","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":100,"description":"The maximum number of keys to return","example":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"description":"Use this to fetch the next page of results. A new cursor will be returned in the response if there are more results."},"required":false,"name":"offset","in":"query"},{"schema":{"type":"string","minLength":1,"description":"If provided, this will only return keys where the `ownerId` matches."},"required":false,"name":"ownerId","in":"query"}],"responses":{"200":{"description":"Keys belonging to the api","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/Key"}},"total":{"type":"integer","description":"The total number of keys for this api"}},"required":["keys","total"]}}}},"400":{"description":"The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrBadRequest"}}}},"401":{"description":"Although the HTTP standard specifies \"unauthorized\", semantically this response means \"unauthenticated\". That is, the client must authenticate itself to get the requested response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrUnauthorized"}}}},"403":{"description":"The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrForbidden"}}}},"404":{"description":"The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrNotFound"}}}},"409":{"description":"This response is sent when a request conflicts with the current state of the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrConflict"}}}},"429":{"description":"The user has sent too many requests in a given amount of time (\"rate limiting\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrTooManyRequests"}}}},"500":{"description":"The server has encountered a situation it does not know how to handle.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrInternalServerError"}}}}}}}}} |