Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

isarantoglou's avatar

What kind of id should I use for API endpoints?

Hello,

I am buidling an API and I am puzzled as to what unique API id for each record I should generate. There are 2 options:

  1. UUID
  2. a random string with a prefix (for example, contacts will be cnt_Am5gg1Q3vPD6XUg, invoices will be inv_ZvjOXxNuLIYqEL etc).

I lean towards the 2nd option but what is the best practice? I am thiking that with the 2nd option the support can identify really easy what kind of id is that since it has a prefix.

Thank you, Ilias

0 likes
4 replies
Sinnbeck's avatar

If you want it to obfuscated, I would go with uuid. You are certain to never end up with 2 items with the same ID, and its widely used, so people will be able to understand it when you write "uuid"

1 like
Tippin's avatar

I find UUIDs to be a great option. You can of course choose to use incrementing IDs internally, and only expose UUIDs, or just use UUIDs for the PK. Depends on the situation I guess, but I have had no issues with UUID as the PK in many cases, especially using orderedUuid as I believe it bakes in time and is sortable by the database. If you choose UUID for PK, it can be helpful to make a trait that will set your models PK on create, as well as handle the keyType and incrementing properties Eloquent uses by default, which is for incrementing key types.

trait HasUuid
{
    /**
     * When the model is instantiated, set the primary
     * key type to string and disable incrementing.
     *
     * @return void
     */
    public function initializeHasUuid(): void
    {
        $this->setKeyType('string');
        $this->setIncrementing(false);
    }

    /**
     * On model creating, set the primary key to UUID.
     *
     * @return void
     */
    public static function bootHasUuid(): void
    {
        static::creating(function (Model $model) {
            $model->{$model->getKeyName()} = Str::orderedUuid()->toString();
        });
    }
}
class User extends Model
{
    use HasUuid;
}
1 like
martinbean's avatar

@isarantoglou UUIDs. Then someone can’t just enumerate your API’s IDs and harvest your data.

The second approach that companies like Stripe uses shouldn’t be needed if you have well-defined endpoints. Like, you should know what results are coming back based on the endpoint you’re interacting with.

1 like
isarantoglou's avatar

Thank you for your responses.

@tippin I did not know about the orderedUuid but as I read it is still outside the RFC (not that i matters alot)

@martinbean Yes, I was checking Stripe API and since its so well known I thought of it as a solution for exposing IDs to the API. I ended up using UUIDv4 since its more "formal".

Also, I noticed MariaDB 10.7 is adding UUID support that will reduce the space needed to store them :)

Please or to participate in this conversation.